Tag: c preprocessor

在Linux内核源代码中遇到Abstruse #define宏

get_cpu_var marcro,定义如下 29 #define get_cpu_var(var) (*({ \ 30 extern int simple_identifier_##var(void); \ 31 preempt_disable(); \ 32 &__get_cpu_var(var); })) 似乎是不可理解的。我假设它是一种函数宏,它返回一个变量指针(基于星号)或者它是某种函数指针。我甚至接近它?有人能启发我吗?

附加到__VA_ARGS__

我知道我可以这样做: #define MACRO(api, …) \ bool ret = api(123, ##__VA_ARGS__); 这只是一个例子,它是更复杂的解决方案的一部分。 关键是我需要将可变数量的参数附加到第一个123. ##使编译器在123参数之后删除逗号,如果没有参数传递给MACRO。 但现在我想向api附加参数,如下: #define MACRO(api, …) \ bool ret = api(__VA_ARGS__##, 456); 诺坎多。 一种解决方案是使用两个宏,MACRO和MACRO_V,并使_V版本不处理任何参数。 但有没有办法让它与一个宏一起工作?

生成反向位查找表(8位)背后的算法

我在这里找到了查找表。 该表生成为8位的反向位表。 我无法弄清楚它为何起作用。 请解释它背后的理论。 谢谢 static const unsigned char BitReverseTable256[256] = { # define R2(n) n, n + 2*64, n + 1*64, n + 3*64 # define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16) # define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 ) R6(0), […]

预处理程序令牌扩展

我对预处理器如何工作的心理模型显然是不完整的,这让我发疯。 我想连接两个标记,但第二个标记应该首先扩展。 #define ANSWER 42 #define FOO foo_ ## ANSWER 在这里, FOO扩展为foo_ANSWER ,但我希望它是foo_42 。 所以我定义了一个MERGE宏,希望在串联之前以某种方式扩展参数: #define MERGE(x, y) x ## y #define BAR MERGE(bar_, ANSWER) 但BAR仍然扩展到bar_ANSWER而不是bar_42 。 所以我定义了另一个宏HELPER : #define HELPER(x, y) MERGE(x, y) #define BAZ HELPER(baz_, ANSWER) 现在BAZ成功扩展到baz_42 。 目前,这对我来说似乎很神奇。 任何人都可以向我解释这种行为吗? 扩展规则如何正常工作?

你可以#define在C中发表评论吗?

我正在尝试做一个调试系统,但它似乎无法工作。 我想要完成的是这样的事情: #ifndef DEBUG #define printd // #else #define printd printf #endif 有没有办法做到这一点? 我有很多调试消息,我不想这样做: if (DEBUG) printf(…) code if (DEBUG) printf(…) …

我应该为OS X特定代码使用什么C预处理器条件?

我应该为OS X特定代码使用什么C预处理器条件? 如果我正在编译OS X,我需要包含一个特定的库,如果我正在编译Linux,我需要包含一个不同的头。 我知道有__APPLE__但我不知道这是否是OS X 10.x的当前条件。

如何在编译时在gcc中显示#define的值

到目前为止,我已经达到了: #define ADEFINE “23” #pragma message (“ADEFINE” ADEFINE) 哪个有效,但是如果ADEFINE不是字符串怎么办? #define ADEFINE 23 #pragma message (“ADEFINE” ADEFINE) 原因: 警告:格式错误的’#pragma message’,被忽略 理想情况下,我希望能够处理任何值,包括undefined。

Variadic UNUSEDfunction/宏

抑制C编译器有关未使用变量的警告的一种众所周知的可移植方法是(参见C代码中未使用的参数警告 ): #define UNUSED(x) (void)(x) 我正在寻找一种方法来概括它以获取多个输入(不同类型): void foo(int a, long b, void* c){ /* Want this: */ ALL_UNUSED(a, b, c); /* instead of: */ UNUSED(a); UNUSED(b); UNUSED(c); } 似乎可以做到这一点的一种方法是使用可变参数函数 static inline void ALL_UNUSED(int dummy, …) {} 但是,我怀疑这种解决方案在专家眼中是令人反感的。 是否有符合标准且可移植(即不使用__attribute__((unused)) )方式来制作可变参数UNUSED()函数/宏? 非常感谢! 编辑 在C99或C预处理器的上下文中似乎没有一种干净的方式来执行我的要求。 这就是人生。 在下面的回答中,@ Dabo展示了一种非常有趣的方式来做我要求使用的一系列宏。 这是整洁和翔实的(至少对我而言),所以我接受了这个答案。 也就是说,我不会将它部署在一个大型项目中,因为它的篇幅足以超过它带来的好处(在我看来)。 但人们会在这里得出不同的结论。 如下所述,使用空可变参数函数的方法也不完美。 虽然它是一个非常优雅的单行,但它会引发关于单元化变量的警告(如果它们是)。 此外,你必须相信你的编译器完全优化它,我原则上反对,但我尝试过的所有编译器实际上都是这样做的。 一个相关的情况是在早期高级接口设计阶段之后存根function。 然后你未使用的变量都将是函数参数并按定义初始化,以下方法可以正常工作 static inline […]

C ++宏:操作参数(具体示例)

我需要更换 GET(“any_name”) 同 String str_any_name = getFunction(“any_name”); 困难的部分是如何修剪引号。 可能? 有任何想法吗?

宏中的意外结果

我有一个简单的程序来计算立方体的体积。 它运行良好,但我得到的结果是错误的。 它的出现是“Y是392”。 任何人都可以帮助我理解为什么它是392? 我刚刚开始使用C,所以我不了解所有的代码。 我意识到这个宏写的很糟糕,我只是想在重写它之前理解它的行为。 #define CUBE(x) (x*x*x) void main(void); void main(void){ int x, y; x = 5; y = CUBE(++x); printf(“Y is %d \n”, y); }