为什么可以int _ $ [:> = <% – !。0,}; 编译?
今天我发现了一些奇怪的语法
int _$[:>=<%-!.0,};
在一些旧的代码中,但实际上代码没有被评论。 这条线似乎没有编译错误报告。 我单独testing它也可以编译:
int main(){ int _$[:>=<%-!.0,}; return 0; }
为什么可以编译?
使用Digraph (见下文),该行被转换为:
int _$[]={-!.0,};
在右侧, .0
是double
字面!
是逻辑否定运算符, -
是算术否定运算符,并且是尾随逗号。 一起{-!.0,}
是一个数组初始值设定项。
左边的int _$[]
定义了一个int
数组。 但是,最后一个问题是, _$
不是标准C中的有效标识符。有些编译器(例如gcc )支持它作为扩展。
C11§6.4.6标点符号
在语言的所有方面,这六个令牌
<: :> <% %> %: %:%:
performance得分别与六个令牌相同
[ ] { } # ##
好,
- 下划线
_
是一个允许的标识符字符, - 美元符号
$
在某些实现中也是允许的 , - 左括号
[
表示types应该是数组, -
:>
是有向图]
, - 等于
=
是赋值, -
<%
是{
的有向图, -
-!.0
只是-1(.0
是一个双字面量0.0
,!隐式地转换为(int) 0
并逻辑反转,而-
为负值), - 数组初始值设定项{1,(2,3,)}中可以有尾随逗号,
- 和
;
结束声明。
所以你明白了
int _$[] = {-1,};
如果我们replace你的代码行中的有向图:>
和<%
,我们就结束了
int _$[]={-!.0,};
相当于
int _$[] = { -1, };
它是一个具有初始值的types为int [1]
的数组_$
的声明。
请注意,由于标准C语言不能立即为标识符中的$
字符提供支持,因此不能完全保证编译。 它允许实现扩展一组受支持的字符。 显然你使用的编译器在标识符中支持$
。
这是因为C中的有向图 。所讨论的行解码如下:
int _$ [ :> = <% - ! .0 , } ; int _$ [ ] = { - ! 0.0 , } ;
此外:
-
.0
是一个double
字面意思。 -
!
是布尔否定运算符,所以!.0
得出(int) 1
。 -
-
是一元否定运算符,它产生(int) -1
。 - 数组元素后面的逗号是合法的。