Вместо этого 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
_Complex
числами. После некоторого чтения в стандарте и предоставленной ссылке я думаю, что ответ @iharob правильный._Complex
тип. Я обнаружил это при написании программного обеспечения для обработки данных для моей диссертации (на самом деле физика, а не информатика или что-то подобное ) - ( мне пришлось применить фильтр нижних частот, поэтому свертка, быстрое преобразование Фурье, так что fftw ).Ответы:
Это расширение gcc и
2i
мнимая константа . Итак, вы можете написать сложное число так:#include <complex.h> _Complex x = 4 + 5i;
источник
_Complex
типа,2i
является константой ( в понимании gcc ). Добавьте флагstd=c99
или вstd=c11
сочетании с,-Wall
и вы увидите предупреждение. Кроме того, он действительно не возвращается,0
но поскольку тип возврата должен быть_Complex
и значением0 + 2i
, вы не можете его проверитьprintf()
. Так что, возможно, это только настоящая часть0
!#include <float.h>
(илиmath.h
) получать поддержку констант с плавающей запятой .#pragma
, которыйcomplex.h
может выдавать. Но они этого не сделали.2i
являетсяgcc
расширением комплексного целочисленного литерала, чисто мнимого числа, удвоенного квадратного корня из-1
. Это расширение также поддерживаетсяclang
.Несколько удивительно, что ваша компиляция с помощью
gcc 5.4.0
дает опубликованный вывод сборки:gcc
5.3.0http://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
Попробуйте последний вариант с помощью редактора раскраски синтаксиса
;-)
источник