2014-02-14 56 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 –