整数文字的types不是默认的int?
我刚刚回答了这个问题 ,它问到为什么迭代循环要花费更多的时间(10分钟后OP才会中止),直到迭代到10亿次为止:
for (i = 0; i < 10000000000; i++)
现在我和其他人的明显答案是,这是由于迭代variables是32位(从未达到100亿),并且循环变得无限循环。
但是,虽然我意识到这个问题,我仍然想知道在编译器内部究竟发生了什么?
由于文字没有附加L
,因此它应该是int
types,因此也是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或八进制常量,也允许使用unsigned
types – 但是每一个都在列表中对应的符号之后 )
所以很显然,在这种情况下,常量被解释为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