2016-12-12 3 views
1

В C, я использовал, чтобы иметь возможность использовать isnan макрос без скобок в if состоянии, как это:C Условный оператор скобки с IsNaN макро

#include <math.h> 
#include <stdio.h> 
void main() { 
    float x,y,z; 
    x=0; y=0; z=x/y; 
    if isnan(z) {   // <--- no parens around isnan 
     printf("z isnan!"); 
    } 
} 

компилируется на Ubuntu 15.10 с GCC 5.2. 1-22ubuntu2.

Однако на Ubuntu 16.04.1 LTS с GCC 4.7.4-3ubuntu12, я получаю эту ошибку компилятора GCC:

флаг
error: expected '(' before '__builtin_isnan' 

Какой компилятор позволяет мне опускать скобки в if состоянии?

+0

Нет, компилятор не позволит вам опустить скобки вокруг оператора 'if', хотя они могут быть предоставлены макросом (препроцессором). Ваш код отлично работает в MSVC, где (см. Следующий комментарий) 'isnan' является макросом * только на C *. –

+0

isnan определяется как макрос в некоторых версиях и как функция в других. в c99 это макрос, поэтому опускание скобки может работать, так как оно должно быть заключено в скобки (как в примере @WeatherVane). возможно, '-std = c99' будет работать. –

+0

Ссылка на комментарий от @ A.S.H Я редактировал свой предыдущий, который сказал: это может зависеть от того, как вы его реализуете. В MSVC я могу иметь # #define TEST (x) (a == x) ', а затем' int a = 1; если TEST (1) printf («Да \ n»); 'и никаких скобок не требуется. –

ответ

1

Никакой флаг компилятора не допускает этого.

компилятор (или, скорее, файл заголовка) в вашей реализации, где он работал, вероятно, определяется isnan() как макрос в вмещающих скобках, например

#define isnan(_x) (__builtin_isnan(_x)) 

Какой бы иметь побочный эффект разрешения поведение, которое вы использовали.

Однако определение isnan() является реализацией, поэтому (между прочим) не требуется быть макросом, заключенным в круглые скобки.

Вам было бы лучше, практически, положить все ваши обычаи if isnan(x) с if (isnan(x)). Это гарантирует, что ваш код работает, даже если ваш компилятор или стандартная библиотека обновлены, или если ваш код портирован на другой (C99 или более поздний) компилятор.

+0

Спасибо. Из любопытства, как бы я нашел определение 'isnan'? – ConvexMartian

+0

Посмотрите в заголовке '', который поставляется вместе с вашим компилятором. Вероятно, это файл с именем 'math.h' в пути include, используемом вашим компилятором. Для gcc посмотрите [link] (https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html). Если в этом файле есть директивы '# include', посмотрите именованные файлы .... ПРИМЕЧАНИЕ. Я настоятельно рекомендую не редактировать стандартные файлы заголовков, поскольку они могут быть перезаписаны в любое время, когда обновляется ваш компилятор/библиотека. – Peter

+0

Спасибо @Peter. Файл '/ usr/include/math.h' определяет' isnan' в значительной степени, как вы описали в своем ответе. – ConvexMartian

Смежные вопросы