Чому твердження “2i;” НЕ викликати помилку компілятора?


82

Замість 2*i, я необережно написав 2i:

Я очікував, що компілятор виявить помилку. Але цього не сталося. Тож чи 2iсправжнє твердження на мові C? Якщо так, то що це робить? Спантеличений!

Я скомпілював за допомогою gcc версії 5.3.0 і ось вихід збірки:


Що це за компілятор?
Іхароб Аль Асімі

Я не працюю з _Complexцифрами. Після прочитання стандарту та наданого посилання, я думаю, що відповідь @ iharob правильна.
занадто чесний для цього сайту

@Olaf Фастет-перетворення Фур'є на Заході fftw використовує _Complexтип. Я з’ясував це під час написання програм для обробки даних для дипломної роботи ( насправді фізика, а не інформатика або подібне ) - ( мені довелося застосувати фільтр низьких частот, настільки згортка настільки швидке перетворення Фур’є, так fftw ).
Іхароб Аль Асімі

@iharob: Хм, це швидше, ніж ffte, і якщо ні, чи можу я використовувати швидше, якщо я живу на заході, але на схід від вас? ;-) Серйозно: дякую за інформацію. Як виглядає, стандарт С навіть не підтримує подібні прості позначення з С11.
занадто чесний для цього сайту

Дуже хороший приклад ".. не" Еврика ", а" Це смішно ... ""!
Jongware

Відповіді:


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могло видавати. Але вони зробили це не так.
Бармар

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.