【问题标题】:GCC Compile-time checking of constant function inputs常量函数输入的 GCC 编译时检查
【发布时间】:2012-02-25 04:52:21
【问题描述】:

如果编译器知道函数输入是常量,我想使用 gcc 对函数输入进行一些编译时检查。

我有一个几乎有效的解决方案,据我所知,它应该有效。

注意:__builtin_constant_p(expression) 应该返回一个表达式在编译时是否已知为常量。

假设我们要在调用 uart(port) 时检查端口是否

#include <stdio.h>

void _uart(int port) {
 printf("port is %d", port);
}

#define uart(port) \
 static_assert(__builtin_constant_p(port)? port<2: 1, "parameter port must be < 2"); \
 _uart(port)

int main(void) {
 int x=1;
 uart(x);
}

这在调用 uart() 时有效。不幸的是,它不适用于非常量 x。由于某种原因 static_assert 无法处理 x 不是常量的情况,即使理论上 __builtin_constant_p() 甚至不会将其传递给常量。我得到的错误信息是:

c:\>gcc a.cpp -std=c++0x -Os
a.cpp: In function 'int main()':
a.cpp:13: error: 'x' cannot appear in a constant-expression

有什么想法吗?

【问题讨论】:

  • “出于某种原因”是“常量表达式”的形式语法没有 ? 运算符的规则,即“如果左侧可证明是 false 在编译时,则第二个参数不需要是常量表达式。” “常量表达式”的语法说“所有组件(即使是在评估时最终未使用的组件)都必须是常量表达式。”这就是错误消息显示“不能出现在常量表达式中”而不是“不能出现在常量表达式的计算部分中”的原因。

标签: gcc constants compile-time


【解决方案1】:

您的代码适用于 g++ (GCC) 4.8.2。

- 但正如您正确指出的那样,没有优化。

如果我们可以使用

static_assert(__builtin_choose_expr(__builtin_constant_p(port), \
                          port<2, 1), "parameter port must be < 2")

- 但不幸的是,__builtin_choose_expr 构造目前仅适用于 C。

但是,有一个 C++ patch 遗憾的是尚未发布。

【讨论】:

  • Hmmm ...你说得对,它符合但实际上并没有做我想要的,因为我忘记添加编译器优化参数:我现在添加了“-Os”,它重现了这个问题很好。
【解决方案2】:

你可以试试 Linux 内核中使用的技巧:

What is ":-!!" in C code?

(有些可怕的)Linux 内核宏对参数中允许的表达式类型没有那么严格。

【讨论】:

    猜你喜欢
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2013-09-29
    • 1970-01-01
    相关资源
    最近更新 更多