Является ли сдвиг слева (<<) отрицательным целым числом 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.

В любом случае формулировка (или объяснение) должна быть затянута/расширена, чтобы сделать ее менее двусмысленной.