【问题标题】:block statements, commas, and control expressions in C [duplicate]C中的块语句、逗号和控制表达式
【发布时间】:2023-11-24 15:08:02
【问题描述】:

我尝试阅读标准的相关部分(c99 的第 6.5 和 6.8 节),但这让我更加困惑并且没有明确的答案。这是有问题的代码:

#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。

【问题讨论】:

  • 这是我不希望看到的代码类型——即使它可以编译 ^_^
  • OT:为了便于阅读,请按照惯例为#defines 使用大写字母:#define BLOCK ...#define block ...
  • 以这种方式组合语句表达式的({}) 是非常糟糕的风格。 Gcc 的人至少应该创建特殊的令牌来禁止这种事情。
  • @claptrap 我下。我这样写是为了更好地说明我的问题。

标签: c c99 c11


【解决方案1】:

没有。它在标准 C (C99/C11) 下无效。

在 GNU C 中有效,扩展名为 statement expressions

【讨论】:

  • 如果不麻烦的话,能否指点一下标准中的相关部分?
  • @SamParker Standard 只讨论它定义的内容,而不是的内容。如果您想查看某种证明,则可以查看here,上面写着:GNU C provides several language features not found in ISO standard C. (The -pedantic option directs GCC to print a warning message if any of these features is used.) To test for the availability of these features in conditional compilation, check for a predefined macro __GNUC__, which is always defined under GCC.
  • 如果你想检查是否有 GCC 扩展,那么编译:gcc -std=c99 -pedantic -Wall -Wextra file.c 会给出关于大多数(不幸的是不是全部)扩展的警告。您也可以查看extensions provided by gcc 的列表以熟悉自己。
  • 扩展并没有被 std 关闭,这有点令人沮丧。我将尝试深入研究 gcc 的文档以进一步调查此问题。感谢您的详细回复。非常感谢。
【解决方案2】:
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 为语句表达式生成警告。

【讨论】:

    【解决方案3】:

    它在 clang 和 gcc 上编译

    不,它没有。将其编译为 C 语言,而不是“GNU goo”语言。

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

    【讨论】:

    • 我用 -std=c99 -Wall -Wextra 编译它,没有产生错误信息。我认为 -std 会关闭所有扩展。我承认我没有包含 -pedantic-errors