2014-02-14 89 views
0

我試過閱讀標準(secs 6.5和6.8 of c99)的relavent部分,但是這導致我更加困惑,沒有明確的答案。這是有問題的代碼:C語言塊語句,逗號和控制表達式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:'#定義BLOCK ...'但是'#define block ...' – alk

+0

以這種方式組合語句表達式的'({'和'})''是非常糟糕的風格。海灣合作委員會的人至少應該創建特殊的令牌,以抑制這樣的事情。 –

回答

4

不是。它在標準C(C99/C11)下無效。

它在GNU C中是有效的,擴展名爲statement expressions

+0

如果沒有任何問題,你能指點我標準中的相關部分嗎? –

+0

@SamParker標準只討論它定義的*什麼,不是什麼*不*。如果你想看到某種證明,那麼你可以看看[這裏](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)) 

這將評估爲一個語句表達式,後跟一個逗號運算符。塊表達式的返回值是塊中最後一條語句的值。逗號運算符從左到右計算,其值等於最後一個表達式。如果您嘗試在gcc的-E選項,你會得到預處理代碼,它看起來像這樣:

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

所以if語句僅由T%2的值確定的條件(按逗號運算符)。

Is the code valid c99/c1x? 

編號C99爲語句表達式生成警告。

1

它編譯於鐺和gcc

不,它不需要。將它編譯爲C語言,而不是「GNU goo」語言。

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

我用-std = c99 -Wall -Wextra編譯它,並且沒有產生錯誤消息。我認爲-std會關閉所有分機。我承認我沒有包含-pedantic-errors –