왜“2i;” 컴파일러 오류가 발생하지 않습니까?


82

대신 2*i나는 부주의하게 썼다 2i.

int foo(int i)
{
    2i;
    return 2i;
}

컴파일러가 오류를 잡을 것으로 예상했습니다. 그러나 그렇지 않았습니다. 그렇다면 2iC에서 유효한 진술입니까? 그렇다면 그것은 무엇을합니까? 어찌할 바를 모르는!

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

그게 무슨 컴파일러 야?
Iharob Al Asimi 2016

나는 _Complex숫자로 일하지 않습니다 . 표준 및 제공된 링크를 읽은 후 @iharob의 대답이 정확하다고 생각합니다.
이 사이트에 대한 너무 정직

@Olaf West fftw 의 fastet Fourier Transform 은 _Complex유형을 사용합니다 . 내 논문 (대한 데이터 처리 소프트웨어를 쓰는 동안 나는이 밖으로 발견 물리학 사실이 아닌 컴퓨터 과학 또는 모두 (-) 그래서 고속 푸리에 그래서 FFTW, 변환 회선 그래서, 로우 패스 필터를 적용했다 ).
Iharob Al Asimi 2016

@iharob : 흠, 그게 ffte보다 빠르지 않으면 내가 서쪽에 살면 더 빠른 것을 사용할 수 있지만 동쪽에 살 수 있습니까? ;-) 진지하게 : 정보 감사합니다. 보시다시피 C 표준은 C11과 유사한 간단한 표기법도 지원하지 않습니다.
이 사이트에 대한 너무 정직

".. 'Eureka'가 아니라 'That 's funny ...'"의 아주 좋은 예!
Jongware

답변:


107

이것은 gcc 확장 이며 2i허수 상수 여기에 이미지 설명 입력입니다. 따라서 다음과 같이 복소수를 쓸 수 있습니다.

#include <complex.h>

_Complex x = 4 + 5i;

12
와우, 놀랐습니다! complex.h 헤더 파일을 포함하지 않았는데도 왜 작동했는지 말씀해 주시겠습니까?
daltonfury42

4
@ daltonfury42 헤더는 _Complex유형을 위한 것이고 2i상수 ( gcc가 이해하는대로 )입니다. 와 결합 된 std=c99또는 std=c11플래그를 추가하면 -Wall경고가 표시됩니다. 또한 실제로 반환되지는 않지만 반환 0유형이이어야 _Complex하고 값이 되어야하므로으로 0 + 2i검사 할 수 없습니다 printf(). 그래서 아마도 그것은 진짜 부분 일 것입니다 0!
Iharob Al Asimi

12
@ daltonfury42 : 부동 소수점 상수에 대한 지원을받을 필요가 없습니다 #include <float.h>(또는 math.h) .
이 사이트에 대한 너무 정직

2
@ daltonfury42 맞습니다. 헤더 파일은 언어 구문을 변경하지 않고 변수, 함수, 유형 등과 같은 것을 선언합니다.
Barmar

2
@ daltonfury42이 구문의 인식이 #pragma, complex.h문제 가 될 수 있는 에 의해 제어 될 수 있었을 수도 있습니다. 그러나 그들은 그렇게하지 않았습니다.
Barmar

13

2igcc복소수 정수 리터럴 의 확장으로,의 제곱근의 두 배인 순수 허수입니다 -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.
  • 함수 foo에 대해 게시 된 어셈블리 코드 가 올바르지 않습니다.을 반환하지 않습니다 0. 복잡한 정수 상수 2i를로 변환하면 int실수 부분을 반환해야합니다 0.

반대로 clang3.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

구문 색상 편집기로 마지막 시도 ;-)


글쎄, 이것은 내가 Arch Linux를 실행하는 PC에서 GCC 5.3.0을 사용했을 때 얻은 것입니다. 여기에 당신이 관심이 있다면 내 GCC 구성입니다.
daltonfury42 2012
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.