Является ли сдвиг слева (<<) отрицательным целым числом undefined в С++ 11?
Отклоняется слева от отрицательного 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 является правильной.
Ответы
Ответ 1
Да, я бы сказал это 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;
Я бы сказал, что причина, по которой они явны в отношении правого операнда, а не левого, состоит в том, что парагрпах, которые вы указываете (тот, который имеет дело с правом операнда), применяется как к левому, так и к правые сдвиги.
Для левого операнда решение отличается. Левое смещение отрицательного - это undefined, правое смещение - это реализация.
Ответ 2
Если это следует понимать как означающее, что сдвиг влево любого отрицательного числа равен UB?
Да, поведение undefined при задании любого отрицательного числа. Поведение определяется только в том случае, если выполняются оба следующих условия:
- число неотрицательно
- E1 × 2 E2 представляется в виде результата
Это буквально то, что "если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2 E2 представляется в типе результата, то это результирующее значение, в противном случае поведение undefined", говорит:
if X and Y
then Z
else U
Ответ 3
Ответьте на вопрос:
На самом деле вопрос:
Можно ли приравнивать термин "поведение undefined" точно соответствует термину "Undefined Поведение".
Как он в настоящее время сформулирован, это означает "Undefined Поведение".
Личный комментарий о ситуации
Но я не уверен, что это намерение авторов.
Если это намерение авторов, то, вероятно, нам следует пояснить, почему. Но я больше склонен полагать, что автор имел в виду, что результатом этой операции является undefined, потому что представление отрицательных чисел не определено явно стандартом. Если представление отрицательных чисел не определено явно для негативов, то перемещение бит вокруг приведет к значению undefined.
В любом случае формулировка (или объяснение) должна быть затянута/расширена, чтобы сделать ее менее двусмысленной.