为什么可以 int _$[:>=<%-!.0,};编译?
Why can int _$[:>=<%-!.0,}; compile?
今天我发现了奇怪的语法
int _$[:>=<%-!.0,};
在一些旧代码中,但实际上代码没有注释。这行似乎没有编译错误的报告。我单独测试过,也可以编译:
int main(){
int _$[:>=<%-!.0,};
return 0;
}
为什么可以编译?
与Digraph(见下文),该行被转换为:
int _$[]={-!.0,};
右边,.0
是double
字面量,!
是逻辑取反运算符,-
是算术取反运算符,,
是结尾的逗号。 {-!.0,}
一起是一个数组初始值设定项。
左侧 int _$[]
定义了一个 int
数组。然而,还有最后一个问题,_$
不是标准 C 中的有效标识符。一些编译器(例如,gcc)支持它作为扩展。
C11 §6.4.6 Punctuators
In all aspects of the language, the six tokens
<: :> <% %> %: %:%:
behave, respectively, the same as the six tokens
[ ] { } # ##
这是由于 digraphs 在 C 中的作用。有问题的行解码如下:
int _$ [ :> = <% - ! .0 , } ;
int _$ [ ] = { - ! 0.0 , } ;
此外:
.0
是 double
文字。
!
是布尔否定运算符,因此 !.0
产生 (int) 1
.
-
是一元否定运算符,它产生 (int) -1
.
- 数组元素后的尾随逗号是合法的。
如果我们替换您代码行中的二合字母 :>
和 <%
,我们最终会得到
int _$[]={-!.0,};
相当于
int _$[] = { -1, };
它是 int [1]
类型数组 _$
的声明,带有初始值设定项。
请注意,这不能完全保证编译,因为标准 C 语言不会立即提供对标识符中 $
字符的支持。它允许实现扩展支持的字符集。显然你使用的编译器在标识符中支持 $
。
嗯,
- 下划线
_
是允许的标识符字符,
- 美元符号
$
is allowed in some implementations too,
- 左括号
[
表示类型应该是数组,
:>
是 ]
, 的二合字母
- 等于
=
是赋值,
<%
是 {
, 的二合字母
-!.0
只是 -1(.0
是双重文字 0.0
,!
隐式转换为 (int) 0
并在逻辑上反转它,并且 -
为负),
- 您可以在数组初始值设定项 {1, (2, 3,)},
中添加尾随逗号
- 和
;
结束语句。,
所以你得到
int _$[] = {-1,};
今天我发现了奇怪的语法
int _$[:>=<%-!.0,};
在一些旧代码中,但实际上代码没有注释。这行似乎没有编译错误的报告。我单独测试过,也可以编译:
int main(){
int _$[:>=<%-!.0,};
return 0;
}
为什么可以编译?
与Digraph(见下文),该行被转换为:
int _$[]={-!.0,};
右边,.0
是double
字面量,!
是逻辑取反运算符,-
是算术取反运算符,,
是结尾的逗号。 {-!.0,}
一起是一个数组初始值设定项。
左侧 int _$[]
定义了一个 int
数组。然而,还有最后一个问题,_$
不是标准 C 中的有效标识符。一些编译器(例如,gcc)支持它作为扩展。
C11 §6.4.6 Punctuators
In all aspects of the language, the six tokens
<: :> <% %> %: %:%:
behave, respectively, the same as the six tokens
[ ] { } # ##
这是由于 digraphs 在 C 中的作用。有问题的行解码如下:
int _$ [ :> = <% - ! .0 , } ;
int _$ [ ] = { - ! 0.0 , } ;
此外:
.0
是double
文字。!
是布尔否定运算符,因此!.0
产生(int) 1
.-
是一元否定运算符,它产生(int) -1
.- 数组元素后的尾随逗号是合法的。
如果我们替换您代码行中的二合字母 :>
和 <%
,我们最终会得到
int _$[]={-!.0,};
相当于
int _$[] = { -1, };
它是 int [1]
类型数组 _$
的声明,带有初始值设定项。
请注意,这不能完全保证编译,因为标准 C 语言不会立即提供对标识符中 $
字符的支持。它允许实现扩展支持的字符集。显然你使用的编译器在标识符中支持 $
。
嗯,
- 下划线
_
是允许的标识符字符, - 美元符号
$
is allowed in some implementations too, - 左括号
[
表示类型应该是数组, :>
是]
, 的二合字母
- 等于
=
是赋值, <%
是{
, 的二合字母
-!.0
只是 -1(.0
是双重文字0.0
,!
隐式转换为(int) 0
并在逻辑上反转它,并且-
为负),- 您可以在数组初始值设定项 {1, (2, 3,)}, 中添加尾随逗号
- 和
;
结束语句。,
所以你得到
int _$[] = {-1,};