Tag: c preprocessor

我们可以删除C宏定义中参数周围的括号吗?

从http://c-faq.com/style/strcmp.html ,我学到了以下便利宏: #define Streq(s1, s2) (strcmp((s1), (s2)) == 0) 我想知道为什么在这个宏中使用了这么多括号。 每个括号是用于某个目的还是使用冗余括号的宏,这些括号没有用处? 我们可以删除s1和s2周围的括号并制作这样的宏吗? #define MyStreq(s1, s2) (strcmp(s1, s2) == 0) MyStreq宏对我来说似乎和Streq一样Streq 。 #include #include #define Streq(s1, s2) (strcmp((s1), (s2)) == 0) #define MyStreq(s1, s2) (strcmp(s1, s2) == 0) int main() { printf(“%d %d\n”, Streq(“foo”, “foo”), MyStreq(“foo”, “foo”)); printf(“%d %d\n”, Streq(“fox”, “foo”), MyStreq(“fox”, “foo”)); printf(“%d %d\n”, Streq(“foo”, […]

C99的预处理器中的static_if

是否可以在C99中实现static_if? #define STATIC_IF(COND, …) \ if (COND) MACRO1(__VA_ARGS__); \ else MACRO2(__VA_ARGS__); 我怎样才能在这里正确实现STATIC_IF(…) ? 根据COND ,参数应该传递给MACRO1或MACRO2 ,但两个宏的参数看起来不同。 COND是静态可测试的,类似sizeof (…) > 42 。 #if COND然后#define STATIC_IF MACRO1 …对我的用例不起作用。 我不能使用编译器特定的解决方案。

为什么在C中定义具有相同名称和内容的宏?

我正在研究Linux内核头文件中的if_link.h ,它包含这个枚举: enum { IFLA_UNSPEC, IFLA_ADDRESS, IFLA_BROADCAST, IFLA_IFNAME, IFLA_MTU, IFLA_LINK, IFLA_QDISC, IFLA_STATS, IFLA_COST, #define IFLA_COST IFLA_COST IFLA_PRIORITY, #define IFLA_PRIORITY IFLA_PRIORITY IFLA_MASTER, #define IFLA_MASTER IFLA_MASTER …. } 定义看起来没用; 他们的目的是什么? 为什么只有一些项目有定义?

我可以附加到预处理器宏吗?

在标准C或GNU扩展中有什么方法可以将内容附加到宏定义中吗? 例如 ,给定宏定义为 #define List foo bar 我可以追加bas以便List扩展,就像我定义它一样 #define List foo bar bas ? 我希望我能做到这样的事情: #define List foo bar bas #define List_ Expand(List) #undef List #define List Expand(List_) quux 但我无法弄清楚如何定义Expand()宏,所以它会做我想要的。 动机:我正在沿着以下方面玩歧视/标记的联盟: struct quux_foo { int x; }; struct quux_bar { char *s; }; struct quux_bas { void *p; }; enum quux_type {quux_foo, quux_bar, quux_bas}; struct […]

使用__VA_ARGS__转换在MACRO中传递的所有参数

我有一个宏FOO(…)接收未知数量的参数。 我想把所有这些参数都用于uint。 有没有办法实现它?

C宏是否隐式投射?

我搜索了SO,但没有找到这个具体问题的答案。 如果它已被回答,请原谅我。 如果您有以下内容: #define MACRO 40 您不将它分配给在循环中使用它的变量: for(int i = 0; i < MACRO; i++) {… 然后,perprocessor创建: for(int i = 0; i < 40; i++) {… 然后编译器会将它隐式地转换为int,因为比较是使用int i类型吗? 我看过这个问题#define变量的类型 ,以及Edgar Bonet的一些答案意味着编译器选择如何处理宏的顺序? 这个问题, C ++如何隐式地将参数转换为比较器,如<? ,也有人建议,但只描述了隐式转换如何与两种类型进行比较。 由于宏实际上没有类型,我不确定这是否适用。

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

我正在清理一个现有的C库,无耻地发布它。 预处理器宏NPOT用于在编译时计算给定积分常数表达式的下一个更大的2的幂。 宏通常用于直接初始化。 对于所有其他情况(例如,使用可变参数),存在具有相同function的内联函数。 但是,如果用户传递变量,则算法会扩展为大量的机器代码。 我的问题是: 我可以做些什么来防止用户向我的宏传递除了一个整数常量表达式之外的任何内容? #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 } 我已经尝试过的: 将宏定义为#define NPOT(x) complex_algorithm(x ## […]

C预处理器:stringize宏和身份宏

我想知道这段代码输出背后的原因。 我无法想出答案。 #define f(a,b) a##b #define g(a) #a #define h(a) g(a) void main() { printf(“%s %s”,h(f(1,2)),g(f(1,2))); } PS:输出为12 f(1,2) 。 我以为它是12 12或f(1,2) f(1,2) 。

变量宏,零参数

我正在研究一个调用宏, #define CALL(f,…) FN(f)->call((ref(new LinkedList()), __VA_ARGS__)) 什么时候叫, CALL(print,2,3,4,5); 将2 3 4 5添加到链接列表(,重载以执行此操作)并调用print,其中需要一个按预期工作的链表,但是有些调用不需要参数, CALL(HeapSize); 它仍然需要一个链接列表,但是空的一个,上面不起作用,我试图想出一个可以使用任何一种风格的宏吗? 编辑:挖掘gcc文档我发现在VA_ARGS之前添加##会删除,当没有参数但是我无法嵌套宏时, CALL(print,CALL(HeadSize)); 这会导致CALL未定义错误,如果我分离它的工作调用

预处理器指令应该在一行的开头吗?

前段时间我发现了一个(相当古老的)C编译器,它以这种方式扫描宏(伪代码): if line.startswith(“#include”) or line.startswith(“#define”): … ..哪一种问题对我来说应该放置宏的位置,在一行的开头,如下所示: void stuff() { #if defined(WIN32) || defined(_WIN32) … #else #if defined(__GNUC__) … #else … #endif #endif } 或者更像是这样(因为我这样做,为了提高可读性): void stuff() { #if defined(WIN32) || defined(_WIN32) … #else # if defined(__GNUC__) … # else … # endif #endif } 是一种缩进预处理器代码标准化的方式,也就是说,无论我如何缩进它,它总是以相同的方式工作?