gcc标准头文件中有很多圆括号
为什么在GCC头文件中用括号括起来的常量expression式就像这样?
#define INTMAX_MIN (-9223372036854775807LL) #define INTMAX_MAX (9223372036854775807LL)
如果我这样省略括号,会有什么不同?
#define INTMAX_MIN -9223372036854775807LL #define INTMAX_MAX 9223372036854775807LL
为什么会有'L'后缀? 如果我写下以下内容,会是一样的吗?
#define INTMAX_MIN -9223372036854775807 #define INTMAX_MAX 9223372036854775807
有没有一个实际的用处,或者它总是一样的东西?
我知道'L'代表了很长时间,我也很清楚Cmacros中括号的重要性。 我为了好奇而问这个。
如果你写了
a = 7 INTMAX_MIN;
你会期望得到一个语法错误,因为在它的表面,这将是一个非法的expression。 它会,因为它扩展到
a = 7 (-9223372036854775807LL);
这确实会给你一个语法错误。 但是如果没有括号,它会扩展到:
a = 7 -9223372036854775807LL;
这不会给你一个错误,尽pipe显然不是你想要的。
更一般地说,所有这些定义给看起来像标识符的事物扩展。 在算术expression式中,标识符是一个“主expression式”,但是-9223372036854775807LL不是。 但是,括号内的expression是“主要expression”。
这就是真正的原因。 因此,macros观将看起来像主要expression的东西展开为一种主要expression。 发生什么事情你永远不会感到惊讶。 在编程中,惊喜通常是不好的。
通常这并不重要,但编写定义的人不希望他们经常工作。 他们希望他们一直工作。
尾随LL将这个整数字面量标记为long long
types,通常(在这种情况下是64位)。 如果没有LL后缀,那么文字可能被解释为int,long int或long long int,无论哪个是第一个支持64位值的。 确定这种types可能与确定价值一样重要。
把一个整数常量和一元运算符放在一个macros上,这是一个很好的做法:
#define BLA (-1)
作为一元运算符(在这里)在C中没有最高优先级。后缀运算符比一元运算符具有更高的优先级。 请记住,C没有负常数,例如-1
是一个常量expression式,前面带有-
一元运算符。
另外PC-Lintbuild议在这些macros中join括号:
(规则973):括号#define N(-1)macros'符号'中的一元运算符未括号 – 出现在expression式macros中的一元运算符未被括号括起来。 例如:
#define N -1
用户可能更喜欢将这样的事情括号为:
#define N (-1)
这个答案试图说明为什么需要LL
。 (这不简单。)
其他答案显示为什么需要括号。
我们来编码三个macros,都是十进制常量 。
#define MAXILL (9223372036854775807LL) #define MAXIL (9223372036854775807L) #define MAXI (9223372036854775807)
即使MAXI
没有后缀,也不会inputint
。 MAXI
将具有适合的第一种types,无论是int
, long
, long long
还是扩展的整数types。
尽pipeMAXIL
具有L
后缀,但它将具有它适合的第一个types,无论是long
, long long
还是扩展整数types。
尽pipeMAXILL
具有LL
后缀,但它将具有它适合的第一个types,不pipe是long long
整型还是扩展整型。
在任何情况下,macros都具有相同的值,但是可能有不同的types。
types确定见C11dr§6.4.4.15。
让我们尝试打印它们,并有int
和long
是32位和long long
, intmax_t
是64。
printf("I %d %d %d", MAXI, MAXIL, MAXILL); //Error: type mismatch printf("LI %ld %ld %ld", MAXI, MAXIL, MAXILL); //Error: type mismatch printf("LLI %lld %lld %lld", MAXI, MAXIL, MAXILL); //Ok
最后一行中的三个都是正确的,因为所有三个macros都很long long
,前面的格式说明符和数字之间的types不匹配。
如果我们的int
是32位long
, long long
和intmax_t
是64,那么以下是正确的。
printf("LI %ld %ld", MAXI, MAXIL); printf("LLI %lld", MAXILL);
最大宽度整数types具有格式说明符"%" PRIdMAX
。 这个macros不能扩展到"%ld"
和 "%lld"
来容纳MAXI, MAXIL, MAXILL
。 它被设置为"%lld"
,与intmax_t
相关的intmax_t
需要具有相同的types。 在这种情况下,应该使用long long
formsMAXILL
。
其他实现可以有一个扩展的整数types(如int128_t
),在这种情况下,可以使用实现特定的后缀或一些机制。