今天我发现了奇怪的语法
int _$[:>=<%-!.0,};
Run Code Online (Sandbox Code Playgroud)
在一些旧代码中,但实际上代码没有被注释.似乎没有关于此行的编译错误的报告.我单独测试它也可以编译:
int main(){
int _$[:>=<%-!.0,};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么要编译?
Yu *_*Hao 47
使用Digraph(见下文),该行转换为:
int _$[]={-!.0,};
Run Code Online (Sandbox Code Playgroud)
在右侧,.0是double文字,!是逻辑否定运算符,-是算术否定运算符,并且,是尾随逗号.Together {-!.0,}是一个数组初始化器.
左侧int _$[]定义了一个int数组.但是,最后一个问题,_$不是标准C中的有效标识符.某些编译器(例如,gcc)支持它作为扩展.
C11§6.4.6标点符号
在语言的各个方面,六个令牌
Run Code Online (Sandbox Code Playgroud)<: :> <% %> %: %:%:行为分别与六个令牌相同
Run Code Online (Sandbox Code Playgroud)[ ] { } # ##
dco*_*cow 38
好,
_是允许的标识符字符,$在某些实现中也允许使用美元符号,[表示类型应为数组,:>是有图的],=分配,<%是有图的{,-!.0只是-1(.0是一个双字面0.0,!隐式转换(int) 0并逻辑反转它,并且-是负数),;结束声明.,所以你得到了
int _$[] = {-1,};
Run Code Online (Sandbox Code Playgroud)
Nay*_*uki 11
int _$ [ :> = <% - ! .0 , } ;
int _$ [ ] = { - ! 0.0 , } ;
Run Code Online (Sandbox Code Playgroud)
此外:
.0是一个double文字.!是布尔否定运算符,所以!.0得到(int) 1.-是一元否定运算符,它产生(int) -1.AnT*_*AnT 11
如果我们替换了有向图:>并<%出现在您的代码行中,我们最终会得到
int _$[]={-!.0,};
Run Code Online (Sandbox Code Playgroud)
这相当于
int _$[] = { -1, };
Run Code Online (Sandbox Code Playgroud)
它是带有初始化器_$的类型数组的声明int [1].
请注意,这并不能完全保证编译,因为标准C语言不会立即为$标识符中的字符提供支持.它允许实现扩展支持的字符集.显然,您使用的编译器支持$标识符.