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