整数文字的types不是默认的int?

我刚刚回答了这个问题 ,它问到为什么迭代循环要花费更多的时间(10分钟后OP才会中止),直到迭代到10亿次为止:

for (i = 0; i < 10000000000; i++) 

现在我和其他人的明显答案是,这是由于迭代variables是32位(从未达到100亿),并且循环变得无限循环。

但是,虽然我意识到这个问题,我仍然想知道在编译器内部究竟发生了什么?

由于文字没有附加L ,因此它应该是inttypes,因此也是32位。 所以由于溢出,它应该是一个正常的int范围内的可达性。 要真正地认识到它不能从int到达,编译器需要知道它是100亿,因此将其视为32位以上的常量。

即使没有附加L ,这样的文字是否会被自动提升到拟合(或至less是实现定义的)范围(在本例中至less是64位),并且是这种标准行为? 或者在幕后发生了一些不同的事情,比如由于溢出而导致的UB(实际上是UB的整数溢出)? 如果有的话,标准中的一些引用可能会很好。

尽pipe原来的问题是C,但是我也很感激C ++的答案,如果有的话。

就C ++而言:

C ++ 11,[lex.icon]¶2

整数字面量的types是表6中相应列表中的第一个,其值可以表示。

表6中,对于没有后缀和小数常量的文字,给出:

 int long int long long int 

(有趣的是,对于hex或八进制常量,也允许使用unsignedtypes – 但是每一个都列表中对应的符号之后

所以很显然,在这种情况下,常量被解释为long int (或long long int如果long int太32位)。

注意“太大的文字”会导致编译错误:

如果一个程序的某个翻译单元包含一个不能由任何允许的types表示的整数字面值,那么该程序就是不合格的。

(ibidem,¶3)

在这个例子中很快见到,这提醒我们ideone.com使用32位编译器。


我现在看到,这个问题是关于C …呃,或多或less是一样的:

C99,§6.4.4.1

整数常量的types是其中可以表示其值的对应列表的第一个。

列表与C ++标准中的列表相同。


附录:C99和C ++ 11都允许文字是“扩展整数types”(即其他实现特定的整数types),如果一切都失败了。 (C ++ 11,[lex.icon]¶3; C99,§6.4.4.1¶5)

2005年5月6日标准为ISO / IEC 9899:TC2委员会草案的C标准草案中 ,这些规则与Matteo发现的C ++规则非常相似:

5一个整数常量的types是其中可以表示其值的对应列表的第一个。

 Suffix Decimal Constant Octal or Hexadecimal Constant ------------------------------------------------------------------- none int int long int unsigned int long long int long int unsigned long int long long int unsigned long long int u or U unsigned int unsigned int unsigned long int unsigned long int unsigned long long int unsigned long long int l or L long int long int long long int unsigned long int long long int unsigned long long int Both u or U unsigned long int unsigned long int and l or L unsigned long long int unsigned long long int ll or LL long long int long long int unsigned long long int Both u or U unsigned long long int unsigned long long int and ll or LL 

我仍然想知道编译器内部到底发生了什么

如果你对编译器如何解释代码感兴趣,你可以看看汇编器。

百亿:

 400054f: mov -0x4(%rbp),%eax mov %eax,-0x8(%rbp) addl $0x1,-0x4(%rbp) jmp 40054f <main+0xb> 

所以它只是把它编译成无限循环,如果用10000代替10000000000:

 .... test %al,%al jne 400551