Тест С++. Значит ли бит бит 1 всегда отрицательный?

Я просто сдавал тест на С++, и у меня был следующий вопрос:

В: Каков вывод следующей программы?

#include <iostream>
#include <stdint.h>

using namespace std;

int main() {
    int a = 0;
    for (int8_t i = 1; i > 0; i <<= 1)
        a++;
    cout << a;
    return 0;
}

На выбор были выбраны

  • 8
  • 7
  • Undefined Поведение
  • Ошибка компиляции

"Правильный" ответ был равен 7. Если в ответах было "Реализованное исполнение", я бы выбрал это, поэтому я выбрал Undefined Behavior, который был скорее ближайшим. Я понимаю, что в sign-and-magnitute, 1 дополнение и 2 дополнения ответ будет равен 7. Но не позволяет ли стандарт С++ теоретически допускать любые другие представления чисел? Например, знак и величина, но 0 означает отрицательный?

Правильно ли я верю, что реальный правильный ответ на этот вопрос должен быть поведением, определяемым реализацией, а если нет, не могли бы вы объяснить, почему ответ равен 7 независимо от реализации?

Я прочитал комментарии к вопросу, и кажется, что изначально тип a был char, что, видимо, вызвало множество жалоб на то, подписано ли char или нет, так что тестовый набор изменил его на int8_t. В качестве бонусного вопроса, есть <stdint.h> часть С++? O_O

Ответ 1

Я бы сказал, что это undefined (а не реализация) по другой причине.

От 5.8: 3

Значение E1 << E2 - это E1, сдвинутые слева по E2 битовые позиции; освобожденные биты заполняются нулями. Если E1 имеет неподписанный тип, то результатом будет E1 × 2 E2 уменьшенный по модулю на один больше максимального значения, представляемого в типе результата. В противном случае, если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2 E2 представляется в типе результата, то это результирующее значение; , поведение undefined.

Ответ 2

Если реализация предоставляет необязательный int8_t, ответ должен быть правильным из проекта C99, который содержит ссылки на С++ 11 относительно stdint;

7.18.1.1 Точные целые типы

Имя typedef intN_t обозначает знаковый целочисленный тип с шириной N, без заполнения бит и представление двухкомпонентных дополнений. Таким образом, int8_t обозначает целое число со знаком тип с шириной ровно 8 бит.

Ответ 3

Поскольку сразу был дан ответ, я отвечу на вопрос о бонусе: <stdint.h> - это заголовок C, который доступен на С++. Однако вместо этого используйте новый заголовок С++ <cstdint>.