首页 > 解决方案 > _Static_assert 替换以在 C 中显示值

问题描述

是否可以让编译器错误/警告诊断输出 C11 或 C17 中的编译时计算数值(即不使用模板)?下面的链接使用模板魔术在 C++ 中执行此操作。目的是将其用作 _Static_assert 替换,它打印非相等失败表达式的值。理想情况下,它应该能够将表达式评估为真或假,并且仅在评估失败时才打印。

这显然是依赖于编译器的,所以假设 GCC。

在 static_assert() 编译时显示整数

标签: cgcccompiler-errorsc11static-assert

解决方案


让 GCC 去做这件事出奇的困难。我找到了这个答案:https ://stackoverflow.com/a/35261673/502399这表明了这样的事情:

void error() {
    int array[sizeof(struct X)];
    __builtin_printf("%d", &array);
}

输出类似的东西

foo.c: In function ‘error’:
foo.c:8:21: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int (*)[8]’ [-Wformat=]                      

  __builtin_printf("%d", &array);
                    ~^   ~~~~~~

只要你可以通过 -Wformat 或 -Wall 什么的。

为了查看是否有更简单的方法,我 grep 了该消息的 GCC 源代码,发现参数类型使用特殊的 GCC 特定%qT格式字符串打印,因此我寻找该字符串的其他用途。具体来说,我正在寻找它在错误中的用途,而不是在警告中,这样它就可以在没有警告标志的情况下工作。我发现了一个用途 in binary_op_error(),我从中做了这个例子:

int array[sizeof(struct X)];
int error = 1 / &array;

产生

foo.c:7:15: error: invalid operands to binary / (have ‘int’ and ‘int (*)[8]’)
 int error = 1 / &array;
               ^ ~~~~~~

其他可能性包括

int array[sizeof(struct X)];
int error = __sync_fetch_and_add(&array, 1);

int error = _Generic((int (*)[sizeof(struct X)])0, int: 0);

int foo(double bar);
int error = foo((int (*)[sizeof(struct X)])0);

等等


推荐阅读