为什么声明“2i;”不会导致编译器错误?

时间:2016-02-03 17:27:26

标签: c syntax

而不是double function() ,我不小心写了2*i

2i

我希望编译器能够捕获错误。但事实并非如此。那么int foo(int i) { 2i; return 2i; } 是C中的有效语句吗?如果是这样,它做什么?明白!

我使用gcc 5.3.0编译,这里是程序集输出:

2i

2 个答案:

答案 0 :(得分:106)

这是gcc extension2i是虚常enter image description here。所以你可以像这样写一个复数:

#include <complex.h>

_Complex x = 4 + 5i;

答案 1 :(得分:13)

2i是复数整数文字的gcc扩展名,是-1平方根的两倍纯虚数。此扩展程序也由clang支持。

使用gcc 5.4.0进行编译会产生已发布的程序集输出,这有点令人惊讶:

  • http://gcc.godbolt.org/#上进行编译我从gcc 5.3.0获得了编译错误:http://gcc.godbolt.org/#error: cannot convert '__complex__ int' to 'int' in return
  • 功能foo的已发布汇编代码不正确:它不会返回0。将复数整数常量2i转换为int应返回其实部0

相反,使用clang 3.7,它会在没有警告的情况下编译并生成最佳代码,但当然不是您所期望的:

foo(int):                       # @foo(int)
    xorl    %eax, %eax
    retq

此语法可以按任何顺序与其他后缀组合使用。使用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

使用语法着色编辑器;-)

尝试最后一个