Почему утверждение «2i;» НЕ вызывает ошибку компилятора?


82

Вместо этого 2*iя небрежно написал 2i:

Я ожидал, что компилятор поймает ошибку. Но этого не произошло. Итак, 2iдопустимое утверждение на C? Если да, то что он делает? Озадачен!

Я скомпилировал с помощью gcc версии 5.3.0, и вот результат сборки:


Что это за компилятор?
Ихароб Аль Асими

Я не работаю с _Complexчислами. После некоторого чтения в стандарте и предоставленной ссылке я думаю, что ответ @iharob правильный.
слишком честно для этого сайта

@Olaf Быстрое преобразование Фурье на Западе fftw использует этот _Complexтип. Я обнаружил это при написании программного обеспечения для обработки данных для моей диссертации (на самом деле физика, а не информатика или что-то подобное ) - ( мне пришлось применить фильтр нижних частот, поэтому свертка, быстрое преобразование Фурье, так что fftw ).
Ихароб Аль-Асими

@iharob: Хм, это быстрее, чем ffte, и если нет, могу ли я использовать более быстрый, если я живу на западе, но к востоку от вас? ;-) Серьезно: спасибо за информацию. Кажется, что стандарт C даже не поддерживает аналогичную простую нотацию с C11.
слишком честно для этого сайта

Очень хороший пример «.. не« Эврика », а« Это смешно ... »»!
Jongware 03

Ответы:


107

Это расширение gcc и 2iмнимая константа введите описание изображения здесь. Итак, вы можете написать сложное число так:


12
Вау, это стало неожиданностью! Вы скажете мне, почему это сработало, даже если я не включил заголовочный файл complex.h?
daltonfury42

4
@ daltonfury42 Заголовок предназначен для _Complexтипа, 2iявляется константой ( в понимании gcc ). Добавьте флаг std=c99или в std=c11сочетании с, -Wallи вы увидите предупреждение. Кроме того, он действительно не возвращается, 0но поскольку тип возврата должен быть _Complexи значением 0 + 2i, вы не можете его проверить printf(). Так что, возможно, это только настоящая часть 0!
Ихароб Аль-Асими

12
@ daltonfury42: Вам также не нужно #include <float.h>(или math.h) получать поддержку констант с плавающей запятой .
слишком честно для этого сайта

2
@ daltonfury42 Верно. Заголовочные файлы не меняют синтаксис языка, они просто объявляют такие вещи, как переменные, функции, типы и т. Д.
Бармар

2
@ daltonfury42 Хотя для распознавания этого синтаксиса можно было управлять с помощью a #pragma, который complex.hможет выдавать. Но они этого не сделали.
Barmar 03

13

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.
  • Опубликованный код сборки для функции fooневерен: он не возвращается 0. Преобразование комплексной целочисленной константы 2iв intдолжно возвращать ее действительную часть 0.

И наоборот, в clangверсии 3.7 он компилируется без предупреждения и генерирует оптимальный код, но, конечно, не то, что вы ожидаете:

Этот синтаксис можно комбинировать с другими суффиксами в любом порядке. Компиляция кода ниже clang -Weverythingдает мне соответствующие предупреждения warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]:

Он производит такой вывод в моей среде:

Попробуйте последний вариант с помощью редактора раскраски синтаксиса ;-)


Что ж, это то, что я получил, когда использовал GCC 5.3.0 на своем ПК с Arch Linux. Вот моя конфигурация gcc, если вам интересно.
daltonfury42
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.