为什么声明“2i;”不会导致编译器错误?
而不是2*i ,我不小心写了2i : 
 int foo(int i) { 2i; return 2i; } 
 我希望编译器能够发现错误。 但事实并非如此。 那么2i是C中的一个有效陈述? 如果是的话,它是做什么的? 困惑! 
我编译使用GCC版本5.3.0,这里是汇编输出:
  .file "strange.c" .text .globl foo .type foo, @function foo: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size foo, .-foo .ident "GCC: (GNU) 5.3.0" .section .note.GNU-stack,"",@progbits 
	
 这是一个gcc扩展 ,而2i是虚数常量  。 所以你可以这样写一个复数:
  。 所以你可以这样写一个复数: 
 #include <complex.h> _Complex x = 4 + 5i; 
  2i是一个复数整数字面积的gcc扩展,是-1平方根两倍的纯虚数。 这个扩展也是由clang支持的。 
 使用gcc 5.4.0编译会生成张贴的程序集输出,这有些令人惊讶: 
-  在http://gcc.godbolt.org/上编译我从;gcc5.3.0得到一个编译错误:http://gcc.godbolt.org/#:error: cannot convert '__complex__ int' to 'int' in return:error: cannot convert '__complex__ int' to 'int' in return。
-  函数foo的过帐汇编代码不正确:它不返回0。 将复数整型常量2i转换为int应返回其实部0。
相反,在3.7节,它编译没有警告,并产生最佳的代码,但当然不是你所期望的:
 foo(int): # @foo(int) xorl %eax, %eax retq 
 此语法可以按任何顺序与其他后缀组合。 用clang -Weverything编译下面的代码clang -Weverything给了我适当的警告warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant] : 
 #include <stdio.h> int main() { /* complex integer literals */ printf("sizeof(2i) = %zd\n", sizeof(2i)); printf("sizeof(2ui) = %zd\n", sizeof(2ui)); printf("sizeof(2li) = %zd\n", sizeof(2li)); printf("sizeof(2lli) = %zd\n", sizeof(2lli)); /* complex floating point literals */ printf("sizeof(2.i) = %zd\n", sizeof(2.i)); printf("sizeof(2.fi) = %zd\n", sizeof(2.fi)); printf("sizeof(2e0fi) = %zd\n", sizeof(2e0fi)); printf("sizeof(2e0i) = %zd\n", sizeof(2e0i)); /* alternate order */ printf("sizeof(2il) = %zd\n", sizeof(2il)); printf("sizeof(2ill) = %zd\n", sizeof(2ill)); printf("sizeof(2.if) = %zd\n", sizeof(2.if)); return 0; } 
它在我的环境中产生这个输出:
 sizeof(2i) = 8 sizeof(2ui) = 8 sizeof(2li) = 16 sizeof(2lli) = 16 sizeof(2.i) = 16 sizeof(2.fi) = 8 sizeof(2e0fi) = 8 sizeof(2e0i) = 16 sizeof(2il) = 16 sizeof(2ill) = 16 sizeof(2.if) = 8 
 用你的语法着色编辑器试试最后一个;-)