Отклоняется слева от отрицательного int
Undefined Поведение в С++ 11?
Соответствующие стандартные отрывки здесь: 5.8:
2/Значение E1 < E2 - левые сдвинутые позиции E2; освобождено бит заполнены нулями. Если E1 имеет неподписанный тип, значение результатом является E1 × 2E2, приведенный по модулю на один больше максимального значения представимые в типе результата. В противном случае, если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2E2 представляется в результате type, то это результирующее значение; в противном случае поведение undefined.
Часть меня смущает:
В противном случае, если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2E2 представляется в типе результата, то это результирующее значение; в противном случае поведение undefined.
Должно ли это интерпретироваться как означающее, что левое смещение любого отрицательного числа является UB? Или это означает только если вы LS отрицательный, и результат не соответствует типу результата, тогда это UB?
Кроме того, в предыдущем разделе говорится:
1/Операторы сдвига < и → группа слева направо. сдвиг-выражение: Добавка-выражение сдвиговое выражение < Добавка-выражение shift-expression → additive-expression
Операнды должны иметь интегральный или неперечисленный тип перечисления и осуществляются интегральные рекламные акции.
Тип результата - это продвинутый левый операнд. поведение Undefined, если правый операнд отрицательный или больше чем или равна длине в битах продвинутого левого операнда.
Это делает явным, что использование отрицательного числа для одного из операндов - UB. Если бы UB использовал отрицательный для другого операнда, я бы ожидал, что здесь будет ясно и понятно.
Итак, нижняя строка:
-1 << 1
Undefined Поведение?
@Angew предоставил толкование psodocode стандарта Standardese, которое кратко выражает одну возможную (вероятную) действительную интерпретацию. Другие задаются вопросом, действительно ли этот вопрос касается применимости языка "поведение undefined" по сравнению с нашим (StackOverflow) использованием фразы "Undefined Поведение". Это изменение должно предоставить несколько разъяснений в отношении того, что я пытаюсь спросить.
@Внутренняя интерпретация стандарта:
if (typeof(E1) == unsigned integral)
value = E1 * 2^E2 % blah blah;
else if (typeof(E1) == signed integral && E1 >= 0 && representable(E1 * 2^E2))
value = E1 * 2^E2;
else
value = undefined;
Что этот вопрос действительно сводится к тому, что это - правильная интерпретация на самом деле:
value = E1 left-shift-by (E2)
switch (typeof(E1))
{
case unsigned integral :
value = E1 * 2^E2 % blah blah;
break;
case signed integral :
if (E1 >= 0)
{
if (representable(E1 * 2^E2))
{
value = E1 * 2^E2;
}
else
{
value = undefined;
}
}
break;
}
?
Sidenote, рассматривая это в терминах psudocode, делает это довольно ясным в моем сознании, что интерпретация @Agnew является правильной.