Baa*_*ard 23 c parsing gcc c99
即使是一个老朋友,我担心我不再(完全)完全掌握在C中解析常量.下面的第二个1行无法编译:
int main( void ) { return (0xe +2); }
int main( void ) { return (0xe+2); }
Run Code Online (Sandbox Code Playgroud)
$ gcc -s weird.c
weird.c: In function ‘main’:
weird.c:1:28: error: invalid suffix "+2" on integer constant
int main( void ) { return (0xe+2); }
^
Run Code Online (Sandbox Code Playgroud)
根据C11标准条款6.4.4.2,编译失败的原因可能是0xe + 2被解析为十六进制浮点常量.我的问题是,是否存在在C中编写十六进制和十进制数的简单加法的约定,我不喜欢在解析时依赖于空格.
这是使用gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.9).在预处理(-E)之后停止编译显示编译失败发生在gcc而不是cpp中.
msc*_*msc 20
因为GCC认为这0xe+2是一个浮点数,而这只是两个整数的加法.
根据cppreference:
由于最大的munch,十六进制整数常量
e以及E在操作符+或后面跟随操作符时-,必须与源中的空格或括号分隔操作符:Run Code Online (Sandbox Code Playgroud)int x = 0xE+2; // error int y = 0xa+2; // OK int z = 0xE +2; // OK int q = (0xE)+2; // OK
Lun*_*din 13
我的问题是,是否存在在C中编写十六进制和十进制数的简单加法的约定
惯例是使用空格.这实际上是C116.4§3规定的:
预处理令牌可以用空格分隔; 这包括注释(稍后描述)或空白字符(空格,水平制表符,换行符,垂直制表符和换页符)或两者.
普通空间是常用空间.
在语言中存在类似的异国情调问题,例如:
---a必须改写为- --a.a+++++b必须改写为a++ + ++b.a /// commentb;a / // commentb等等.所有这些情况的罪魁祸首都是令牌解析器,它遵循所谓的"最大咀嚼规则",C116.4§4:
如果输入流已被解析为预处理令牌直到给定字符,则下一个预处理令牌是可构成预处理令牌的最长字符序列.
在这种特定情况下,当预处理器构建一个名为pp-number的预处理令牌时,预处理器不会对浮点常量和整数常量进行任何区分,这在C11 6.4.8中定义:
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number.预处理数字以可选地在句点(.)之后的数字开始,并且可以跟随有效的标识符字符和字符序列e +,e-,E +,E-,p +,p-,P +或P-.
在这里,就预处理器而言,pp-number显然不必是浮点常数.
(作为旁注,在终止字符串内部的十六进制转义序列时也存在类似的约定.如果我想要"ABBA"在新行上打印字符串,那么我就不能写了
puts("\xD\xABBA"); (CR + LF +字符串)
因为在这种情况下字符串可以解释为十六进制转义序列的一部分.相反,我必须使用空格来结束转义序列,然后依靠预处理器字符串连接:puts("\xD\xA" "BBA").目的是一样的,指导预处理器如何解析代码.)
| 归档时间: |
|
| 查看次数: |
1323 次 |
| 最近记录: |