Рассмотрим следующий код:
SomeType x=getX();
for(auto mask = 1u<<(CHAR_BIT*sizeof x - 1);/*...*/;/*...*/)
{
static_assert(sizeof mask>=sizeof x, "Type of numeric parameter is too long");
/*...*/
}
Здесь mask
будет иметь тип unsigned
. Предположим, что SomeType
равно long long
. Тогда инициализация mask
будет иметь неопределенное поведение из-за слишком большого смещения. Но OTOH, есть static_assert
, который проверяет, что неопределенное поведение не может произойти во время выполнения (потому что код не скомпилируется).
Но поскольку UB может привести к временным парадоксам и другим неожиданностям, я не уверен, что static_assert
действительно сработает в этом случае. Есть ли основания быть в этом уверенным? Или этот код следует переделать, чтобы static_assert
отображалось до инициализации mask
?
auto mask = 1u; static_assert(...); mask <<= HAR_BIT*sizeof x-1;
, чтобы полностью избежать этой проблемы. - person R Sahu   schedule 06.03.2019SomeType x=getX(); static_assert(sizeof(x) < whatever_value_you_need, "Type of numeric parameter is too long"); ...
. - person NathanOliver   schedule 06.03.2019static_assert
сразу послеSomeType x = ...;
. Какой смысл делать это в цикле? - person R Sahu   schedule 06.03.20191u
на1ull
в одном месте. Но если я заранее явно объявлюunsigned mask
, чтобы выполнитьstatic_assert
раньше, у меня возникнут две проблемы: 1) маска сохраняется после цикла (для избежания этого требуется дополнительная область видимости), 2) изменение типа в выражении также требует дополнительного изменения типаmask
. - person Ruslan   schedule 06.03.2019(1u << (CHAR_BIT*(sizeof x))) - 1
- person Ben Voigt   schedule 07.03.2019