Я рекомендую зробити це саме так, як ви показали, оскільки це найбільш прямий вперед. Ініціалізуйте, до -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 з кожним типом і машиною.