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 longtypes,通常(在这种情况下是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没有后缀,也不会inputintMAXI将具有适合的第一种types,无论是intlonglong long还是扩展的整数types。

尽pipeMAXIL具有L后缀,但它将具有它适合的第一个types,无论是longlong long还是扩展整数types。

尽pipeMAXILL具有LL后缀,但它将具有它适合的第一个types,不pipe是long long整型还是扩展整型。

在任何情况下,macros都具有相同的值,但是可能有不同的types。

types确定见C11dr§6.4.4.15。


让我们尝试打印它们,并有intlong是32位和long longintmax_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位longlong longintmax_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 longformsMAXILL


其他实现可以有一个扩展的整数types(如int128_t ),在这种情况下,可以使用实现特定的后缀或一些机制。