编写十六进制和十进制数的简单加法的约定
Conventions to write simple additions of hexadecimal and decimal numbers
即使是老朋友,恐怕我(不再)完全掌握 C 中常量的解析。以下 1-liner 中的第二个无法编译:
int main( void ) { return (0xe +2); }
int main( void ) { return (0xe+2); }
$ 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); }
^
编译失败的原因可能是0xe+2按照C11标准条款6.4.4.2被解析为十六进制浮点常量。我的问题是是否存在 约定 来在 C 中编写简单的十六进制和十进制数的加法,我不喜欢在解析时必须依赖白色 space。
这是 gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)。预处理后停止编译(-E)显示编译失败发生在 gcc 而不是 cpp。
因为GCC认为0xe+2
是一个浮点数,而这只是两个整数相加。
根据cppreference:
Due to maximal munch, hexadecimal integer constants ending in e
and E
,
when followed by the operators +
or -
, must be separated from the
operator with whitespace or parentheses in the source:
int x = 0xE+2; // error
int y = 0xa+2; // OK
int z = 0xE +2; // OK
int q = (0xE)+2; // OK
My question is whether a convention exists to write simple additions of hexadecimal and decimal numbers in C
惯例是使用spaces。这实际上是由 C11 6.4 §3 强制执行的:
Preprocessing tokens can be separated by white space; this consists of
comments (described later), or white-space characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both.
其中普通的space是常用的
语言中到处存在类似的奇异问题,一些例子:
---a
必须重写为 - --a
.
a+++++b
必须重写为 a++ + ++b
.
a /// comment
b;
必须重写为
a / // comment
b
等等。所有这些情况的罪魁祸首是遵循 so-called "maximal munch rule"、C11 6.4 §4:
的令牌解析器
If the input stream has been parsed into preprocessing tokens up to a given character, the
next preprocessing token is the longest sequence of characters that could constitute a
preprocessing token.
在这种特定情况下,pre-processor 在构建一个名为 [=64= 的 pre-processing 标记时,不区分浮点常量和整数常量],在C11 6.4.8中定义:
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .
A preprocessing number begins with a digit optionally preceded by a period (.) and may
be followed by valid identifier characters and the character sequences e+, e-, E+, E-,
p+, p-, P+, or P-.
这里,就 pre-processor 而言,pp-number 显然不必是浮点常量。
( 作为旁注,在字符串中终止十六进制转义序列时也存在类似的约定。例如,如果我想在新行上打印字符串 "ABBA"
,那么我不能写
puts("\xD\xABBA");
(CR+LF+字符串)
因为本例中的字符串可以解释为十六进制转义序列的一部分。相反,我必须使用白色 space 来结束转义序列,然后依赖 pre-processor 字符串连接:puts("\xD\xA" "BBA")
。目的是一样的,指导pre-processor如何解析代码。 )
即使是老朋友,恐怕我(不再)完全掌握 C 中常量的解析。以下 1-liner 中的第二个无法编译:
int main( void ) { return (0xe +2); }
int main( void ) { return (0xe+2); }
$ 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); }
^
编译失败的原因可能是0xe+2按照C11标准条款6.4.4.2被解析为十六进制浮点常量。我的问题是是否存在 约定 来在 C 中编写简单的十六进制和十进制数的加法,我不喜欢在解析时必须依赖白色 space。
这是 gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)。预处理后停止编译(-E)显示编译失败发生在 gcc 而不是 cpp。
因为GCC认为0xe+2
是一个浮点数,而这只是两个整数相加。
根据cppreference:
Due to maximal munch, hexadecimal integer constants ending in
e
andE
, when followed by the operators+
or-
, must be separated from the operator with whitespace or parentheses in the source:int x = 0xE+2; // error int y = 0xa+2; // OK int z = 0xE +2; // OK int q = (0xE)+2; // OK
My question is whether a convention exists to write simple additions of hexadecimal and decimal numbers in C
惯例是使用spaces。这实际上是由 C11 6.4 §3 强制执行的:
Preprocessing tokens can be separated by white space; this consists of comments (described later), or white-space characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both.
其中普通的space是常用的
语言中到处存在类似的奇异问题,一些例子:
---a
必须重写为- --a
.a+++++b
必须重写为a++ + ++b
.a /// comment
b;
必须重写为
a / // comment
b
等等。所有这些情况的罪魁祸首是遵循 so-called "maximal munch rule"、C11 6.4 §4:
的令牌解析器If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token.
在这种特定情况下,pre-processor 在构建一个名为 [=64= 的 pre-processing 标记时,不区分浮点常量和整数常量],在C11 6.4.8中定义:
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .A preprocessing number begins with a digit optionally preceded by a period (.) and may be followed by valid identifier characters and the character sequences e+, e-, E+, E-, p+, p-, P+, or P-.
这里,就 pre-processor 而言,pp-number 显然不必是浮点常量。
( 作为旁注,在字符串中终止十六进制转义序列时也存在类似的约定。例如,如果我想在新行上打印字符串 "ABBA"
,那么我不能写
puts("\xD\xABBA");
(CR+LF+字符串)
因为本例中的字符串可以解释为十六进制转义序列的一部分。相反,我必须使用白色 space 来结束转义序列,然后依赖 pre-processor 字符串连接:puts("\xD\xA" "BBA")
。目的是一样的,指导pre-processor如何解析代码。 )