Tag:

宏((void(*)())0)()是什么意思?

以下宏的结果很清楚: #define CRASH() do {\ *(int *)(uintptr_t)0xbbadbeef = 0;\ ((void(*)())0)();\ } while (false) 我的问题是,这条线是什么 ((void(*)())0)(); 用英语分解? 例如,“这是一个返回指针的函数….”

关于`({});`的更多信息?

我注意到有时,C宏被写成这样的东西: #define foo(bar) ({ ++bar; }) 经过一些实验,我发现: ({}); 会编译,但什么都不做。 (正如所料。) 离开; off会导致语法错误。 这样做的副作用是确保foo()看起来像代码中的函数。 (虽然,如果关闭分号,错误对诊断问题不是很有用!) return ({}); 抱怨虚假值不被忽略,就像我试图使用void函数一样。 这只是为了让开发人员在他们的宏中添加分号,还是有另一个目的? 我已经尝试过谷歌,但是标点符号失败了。 这有名字吗?

宏定义中双重否定的目的是什么,如(!!(expr))?

可能重复: C ++代码中的双重否定。 我正在阅读代码库,并找到这样的东西: #define uassert(msgid, msg, expr) (void)((!!(expr))||(uasserted(msgid, msg), 0)) 我无法弄清楚为什么(!!(expr))而不是单个(expr) 。 无论如何,双重否定意味着积极,不是吗? 我错过了什么吗?

预处理器失败,因为 – ‘#’后面没有宏参数

我试图简化数组的声明,但遇到了我正在使用的预处理器的问题。 我的初始代码如下所示: #define REQ_ENTRY(parm_1, parm_2) \ #if defined(parm_1) \ { parm_1, parm_2 }, \ #endif typedef struct { int parm1, parm2; } MyTypedef_t; static const MyTypedef_t MyList[] = { REQ_ENTRY( ID_1, 1 ) REQ_ENTRY( ID_2, 2 ) REQ_ENTRY( ID_3, 3 ) REQ_ENTRY( ID_4, 4 ) REQ_ENTRY( ID_5, 5 ) }; 当然,构建失败,错误消息为“错误:’#’后面没有宏参数”。 这里解释了这个原因( 为什么编译器抱怨这个宏声明 ) 基本上,我试图避免将数组声明为如下,这确实有效: […]

通过在c 中平方宏SQR而感到困惑

这个问题在模拟面试中被问到了……真的很惊讶地找到了尴尬的答案…… 考虑一个宏: #define SQR(x) (x*x) 例1: SQR(2) //prints 4 例2: 如果给出SQR(1 + 1),它不会将(1+1)加到2而是…… SQR(1+1) //prints 3 尴尬吧? 是什么原因? 这段代码是如何工作的? 注意:我搜索了SO,但找不到任何相关问题。 如果有任何好评请分享!

我可以将__func__替换为C宏中的标识符名称吗?

我想写一个C宏,它采用这个: int foo() { MY_MACRO } 并将其扩展为: int foo() { _macro_var_foo++; } 我发现我不能使用__func__ ,因为它实际上并没有在宏中扩展; 它被预处理器像变量一样对待。 有没有办法让这个工作?

有条件的宏扩张

抬头:这是一个奇怪的问题。 我有一些非常有用的宏,我喜欢用来简化一些日志记录。 例如,我可以做Log(@”My message with arguments: %@, %@, %@”, @”arg1″, @”arg2″, @”arg3″) ,这将扩展为更复杂的方法调用包括self , _cmd , __FILE__ _cmd __FILE__ , _cmd等等,以便我可以轻松跟踪记录事件的位置。 这很好用。 现在我想扩展我的宏,不仅可以使用Objective-C方法,还可以使用常规的C函数。 问题是宏扩展中的self和_cmd部分。 C函数中不存在这两个参数。 理想情况下,我希望能够在C函数中使用同一组宏,但我遇到了问题。 当我使用(例如)我的Log()宏时,我得到关于self和_cmd未声明的编译器警告(这完全有道理)。 我的第一个想法是做类似以下的事情(在我的宏中): if (thisFunctionIsACFunction) { DoLogging(nil, nil, format, ##__VA_ARGS__); } else { DoLogging(self, _cmd, format, ##__VA_ARGS__); } 这仍然会产生编译器警告,因为整个if()语句被替换代替宏,导致self和_cmd关键字出错(即使它们在函数执行期间永远不会被执行)。 我的下一个想法是做这样的事情(在我的宏中): if (thisFunctionIsACFunction) { #define SELF nil #define CMD nil } […]

C宏的范围规则

我不是一个C程序员,但我假设C宏几乎是一种查找和替换function,其中预处理器采用宏定义并将其放在它看到宏名称的任何地方。 这是Dragon Book的动态范围规则示例以及它们如何应用于宏: #define a (x + 1) int x = 2; void b () { int x = 1; printf(“%d\n”, a); } void c () { printf(“%d\n”, a); } void main () { b(); c(); } 他们还讨论了动态范围规则如何应用于宏a的名称x 。 我假设它基本上会替换with (x + 1)然后编译程序,因此范围规则与写入(x + 1)而不是a (它将是静态的(x + 1)完全相同范围规则)。 任何人都可以澄清一下吗? 编辑:书中提到的是编译器:原理,技术和工具第二版。 引用的例子来自第31-32页。

C ++宏将字符串转换为字符列表

是否有可能有一个宏: CHAR_LIST(鸡) 扩展到: ‘鸡’ [原因我想要它:因为即使是中等大小的字符串,宏也比手动扩展更方便。 我需要扩展的原因是将字符串传递给varidiac模板]

如何评估嵌套的预处理器宏

假设我想选择某个预处理程序指令的行为,在编译时评估常量字符串和另一个宏的结果的串联。 #define CASE1 text1 #define CASE2 text2 #define CASE3 text3 #define SCENARIO 3 /** the following won’t work – for examplification purposes only**/ #define FUNCTION CASE##SCENARIO /** whenever I write FUNCTION, I expect to see text3 **/ 我很难想到一个可行的解决方案,因为预处理器是一次通过的野兽。 这甚至可行吗?