整数文字的类型默认不是int?

Chr*_*ica 32 c c++ overflow literals

我刚刚回答了这个问题,它问为什么迭代直到for循环中的100亿需要更长时间(OP实际上在10分钟后中止)比迭代直到10亿:

for (i = 0; i < 10000000000; i++)
Run Code Online (Sandbox Code Playgroud)

现在我和其他许多人明显的答案是,这是因为迭代变量是32位(从未达到100亿)并且循环得到无限循环.

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

由于文字没有附加一个L,它应该是IMHO类型int,因此32位.因此,由于溢出,它应该是int范围内的正常可达.为了真正认识到无法从中获取int,编译器需要知道它是100亿,因此将其视为超过32位的常量.

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

虽然最初的问题是C,但我也很欣赏C++的答案,如果有的话.

Mat*_*lia 34

就C++而言:

C++ 11,[lex.icon]2

整数文字的类型是表6中相应列表的第一个,其中可以表示其值.

表6,对于没有后缀和十进制常量的文字,给出:

int
long int
long long int
Run Code Online (Sandbox Code Playgroud)

(有趣的是,对于十六进制或八进制常量,也unsigned允许使用类型 - 但每个都列表中相应的签名之后)

因此,很明显,在这种情况下,常量被解释为long int(或者long long int如果long int是32位).

请注意,"太大的文字"应该导致编译错误:

如果某个程序的翻译单元中包含一个无法用任何允许类型表示的整数文字,则该程序格式不正确.

(ibidem,3)

这个样本中很快就会看到,这提醒我们ideone.com使用32位编译器.


我现在看到问题是关于C ......好吧,它或多或少是相同的:

C99,§6.4.4.1

整数常量的类型是相应列表中可以表示其值的第一个.

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


附录:如果其他一切都失败,C99和C++ 11都允许文字为"扩展整数类型"(即其他特定于实现的整数类型).(C++ 11,[lex.icon]3; C99,§6.4.4.15表后)

  • 当一个值足够小以适应`int`时,`L`后缀很有用,但你希望它仍然是`long`:`42L`是`long`类型.例如:`60*60*24`是86400,如果`int`是16位,它可以溢出; `60L*60L*24L`不会溢出. (11认同)
  • @ChristianRau:在检查标准以回复你的问题之前,我也想过你.:) (2认同)

sar*_*old 11

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

5整数常量的类型是相应列表中可以表示其值的第一个.

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 
Run Code Online (Sandbox Code Playgroud)