Переполнение gcc в выражении, в то время как эквивалентное эквивалентное выражение работает нормально

Вот мой код

#include <iostream>
static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);
static const unsigned long long int y = 36 * 36 * 36 * 36;
static const unsigned long long int yy = y * y;

int main()
{
  std::cout << xx << std::endl;
  std::cout << yy << std::endl;
  return 0;
}

Это вывод компиляции

# g++ -std=c++11 test.cpp -o test
test.cpp:2:62: warning: integer overflow in expression [-Woverflow]
 static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);

Это результат выполнения

# ./test
18446744073025945600
2821109907456

Можете ли вы объяснить, почему я вижу это предупреждение и разные результаты? если 36 может поместиться в char, то 36 ^ 8 может поместиться в unsigned long long int, поэтому я не уверен, в чем здесь проблема, пожалуйста, сообщите. (Я использую gcc 4.9.2)


person e271p314    schedule 19.05.2016    source источник
comment
Кажется, это очень распространенное заблуждение: более позднее намерение каким-то образом влияет на значение более раннего кода. (Где более раннее и более позднее относятся к порядку включения подвыражений.) Обычно это не так в C++; самое близкое, что вы получаете к такому эффекту, - это разрешение перегрузки операндов адреса внутри приведения.   -  person Kerrek SB    schedule 19.05.2016


Ответы (1)


static const unsigned long long int xx = (36 * 36 * 36 * 36) * (36 * 36 * 36 * 36);

36 имеет тип int

36 * 36 имеет тип int

(36 * 36 * 36 * 36) имеет тип int

(36 * 36 * 36 * 36) * (36 * 36 * 36 * 36) имеет тип int и переполняется, что на самом деле является неопределенным поведением для подписанных типов.

Вы, наверное, хотели

static const unsigned long long int xx = (36ull * 36 * 36 * 36) * (36 * 36 * 36 * 36);

Что касается второго случая:

static const unsigned long long int yy = y * y;

y имеет тип unsigned long long

y * y имеет тип unsigned long long, поэтому переполнения нет.

person user657267    schedule 19.05.2016
comment
Опечатка - неопределенное поведение для неподписанных типов - вы имели в виду подписанные, верно? - person Rostislav; 19.05.2016