Я рекомендую зробити це саме так, як ви показали, оскільки це найбільш прямий вперед. Ініціалізуйте, до -1
якого працюватимуть завжди , незалежно від фактичного представлення знаків, тоді як ~
іноді буде дивовижна поведінка, оскільки вам доведеться мати правильний тип операнду. Тільки тоді ви отримаєте найбільш високе значення unsigned
типу.
Для прикладу можливого сюрпризу розглянемо цей:
unsigned long a = ~0u;
Це не обов'язково зберігатиме шаблон з усіма бітами 1 на a
. Але він спочатку створить шаблон із усіма бітами 1 в unsigned int
, а потім призначить його a
. Що відбувається, коли unsigned long
має більше бітів, це те, що не всі з них є 1.
І врахуйте це, яке не вдасться у представленні доповнення, яке не є двома:
unsigned int a = ~0; // Should have done ~0u !
Причиною тому є те, що ~0
має інвертувати всі біти. Інверсія , що дасть -1
на двійкове доповнення машині (це значення нам потрібно!), Але НЕ вихід -1
на інше уявлення. На машині, що доповнює, це дає нуль. Таким чином, на машині доповнення, зазначене вище ініціалізується a
на нуль.
Що ви повинні розуміти, це те, що це все в значеннях, а не в бітах. Змінна ініціалізується зі значенням . Якщо в ініціалізаторі ви модифікуєте біти змінної, використовуваної для ініціалізації, значення буде сформовано відповідно до цих бітів. Значення, яке потрібно для ініціалізації a
до максимально можливого значення, є -1
або UINT_MAX
. Другий буде залежати від типу a
- вам потрібно буде використовувати ULONG_MAX
для unsigned long
. Однак перший не буде залежати від його типу, і це приємний спосіб отримати максимально високе значення.
Ми не говоримо про те, чи -1
має всі біти один (він не завжди є). І ми не говоримо про те, чи ~0
є всі біти один (він, звичайно, є).
Але про що ми говоримо - це результат ініціалізованої flags
змінної. А для цього працюватимуть лише-1
з кожним типом і машиною.