2014-02-14 5 views
0

Я попытался прочитать релевантные разделы стандарта (secs 6.5 и 6.8 из c99), но это привело меня к более запутанному и без четкого ответа. Это код, о котором идет речь:Операторы блоков, запятые и управляющие выражения в C

#include <stdio.h> 
#include <time.h> 

int t; 
#define block {\ 
    int temp = 1; \ 
    t = time(NULL); \ 
    if (t == (time_t) -1 && temp) puts("turbulance ahead!");\ 
} 

int main(){ 
    if (((block), t%2)) { 
     puts("nice 'n even"); 
    } 
    else { 
     puts("odd.."); 
    } 
    return 0; 
} 

Действительно ли код действует c99/c1x? Он компилируется на clang и gcc без каких-либо ошибок, даже когда заданы -Wall и -Wextra.

+3

это тип кода я не хотел бы видеть, - даже если он компилирует^_^ –

+0

OT: Ради readabilty следовать соглашению использовать капиталы для '# define's:' #define BLOCK ... 'but' #define block ... ' – alk

+0

Сочетание выражений выражения' ('и'}) в этом случае действительно плохое. Gcc люди должны, по крайней мере, создать специальные жетоны, которые препятствуют такой вещи. –

ответ

4

№ Недействительно в соответствии со стандартом C (C99/C11).

Это действительный в GNU C, расширение, называемое statement expressions.

+0

Если это не проблема, не могли бы вы указать мне на релевантные разделы в стандарте? –

+0

@SamParker Standard только говорит о том, что * определено * им, а не что это * не * там. Если вы хотите увидеть какое-то доказательство, вы можете посмотреть [здесь] (http://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/C-Extensions.html#C%20Extensions), где он говорит: 'GNU C предоставляет несколько языковых функций, не найденных в стандарте ISO C. (Параметр -pedantic позволяет GCC печатать предупреждающее сообщение, если используется какая-либо из этих функций.) Чтобы проверить наличие этих функций в условной компиляции, проверьте для предопределенного макроса __GNUC__, который всегда определяется под GCC.' –

+0

Если вы хотите проверить, есть ли расширения GCC, то компиляция с помощью: 'gcc -std = c99 -pedantic -Wall -Wextra file.c' будет давать предупреждения о большинство (к сожалению, не все) расширений. Вы также можете просмотреть список [расширений, предоставленных gcc] (http://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/C-Extensions.html#C%20Extensions), чтобы ознакомиться. –

0
if (((block), t%2)) 

Это выражение выражает выражение, за которым следует оператор запятой. Возвращаемое значение блочного выражения - это значение последнего оператора в блоке. Оператор Comma вычисляет слева направо и его значение равно последнему выражению. Если вы попытаетесь опцию -E в НКУ, вы получите препроцессированный код, который выглядит следующим образом:

if ((({ int temp = 1; t = time(((void *)0)); if (t == (time_t) -1 && temp) puts("turbulance ahead!");}), t%2)) 

Так условие, если оператор определяется только величиной т% 2 (в соответствии с оператором запятой).

Is the code valid c99/c1x? 

Номер C99 генерирует предупреждение для выражений оператора.

1

Он собирает на лязгом и НКУ

Нет, это не так. Скомпилируйте его как язык C, а не как язык «GNU goo».

gcc file.c -std=c99 -pedantic-errors -Wall -Wextra 
+0

Я скомпилировал его с -std = c99 -Wall -Wextra, и никаких сообщений об ошибках не было. Я предположил, что -std отключит все расширения. Я признаю, что не включал в себя –