gpt4 book ai didi

c - 如何检查参数是否是 C 预处理器宏中的整型常量表达式?

转载 作者:太空狗 更新时间:2023-10-29 17:23:06 24 4
gpt4 key购买 nike

我目前正在清理现有的 C 库以厚颜无耻地发布它。

预处理器宏 NPOT 用于在编译时 为给定的整数常量表达式计算下一个更大的 2 次幂。该宏通常用于直接初始化。对于所有其他情况(例如使用可变参数),有一个具有相同功能的内联函数。

但是如果用户传递一个变量,算法就会扩展成一大段机器代码。我的问题是:我可以做些什么来阻止用户向我的宏传递除整型常量表达式之外的任何内容?

#define NPOT(x)   complex_algorithm(x)

const int c=10;
int main(void) {
int i=5;

foo = NPOT(5); // works, and does everything it should
foo = NPOT(c); // works also, but blows up the code extremely
foo = NPOT(i); // blows up the code also
}

我已经尝试过的:

  1. 将宏定义为 #define NPOT(x) complex_algorithm(x ## u)。它仍然有效并抛出一个 - 即使几乎没有帮助 - 可变参数的编译器错误。除非没有像 iu 这样的变量……脏,危险,不要。
  2. 文档,对大多数用户不起作用。

最佳答案

您可以使用任何需要常数积分表达式然后将被优化掉的表达式。

#define NPOT(X)                                         \
(1 \
? complex_algorithm(X) \
: sizeof(struct { int needs_constant[1 ? 1 : (X)]; }) \
)

最终您应该将 sizeof 的结果转换为适当的整数类型,因此返回表达式是您期望的类型。

我在这里使用未标记的struct

  • 有一个类型所以真的没有临时产生
  • 有一个独特的类型,这样表达式可以在代码中的任何地方重复而不会引起冲突
  • 触发 VLA 的使用,从 C99 开始,这在 struct 中是不允许的:

A member of a structure or union may have any object type other than a variably modified type.

我正在使用带有 1 的三元 ?: 作为选择表达式,以确保 : 始终根据其类型进行评估,但是从未被评估为表达式。

编辑: 似乎 gcc 接受 struct 中的 VLA 作为扩展,甚至没有警告它,即使我明确地说 -std= c99。这对他们来说真是个糟糕的主意。

对于这样一个奇怪的编译器 :) 你可以使用 sizeof((int[X]){ 0 }) 来代替。这和上面的版本一样“被禁止”,但甚至 gcc 也会提示它。

关于c - 如何检查参数是否是 C 预处理器宏中的整型常量表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9274532/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com