Tag:

possible(x)和__builtin_expect((x),1)

我知道内核使用了likely , unlikely宏。 宏的文档位于内置函数:long __builtin_expect(long exp,long c) 。 但他们并没有真正讨论细节。 编译器究竟如何处理likely(x)和__builtin_expect((x),1) ? 它是由代码生成器还是优化器处理的? 它取决于优化级别吗? 代码生成的示例是什么?

Legit使用C / C ++中的offsetof offset

在C / C ++中有这个宏偏移量,它允许您获取POD结构中成员的地址偏移量。 有关C FAQ的示例: struct foo { int a; int b; }; struct foo; /* Set the b member of foo indirectly */ *(int *)((char *)foo + offsetof(b)) = 0xDEADBEEF; 现在这对我来说似乎是邪恶的,我看不出这个宏的许多合法用途。 我看到的一个合法的例子是它在Linux内核中的container_of宏中用于获取嵌入式结构父对象的地址: /* get the address of the cmos device struct in which the cdev structure which inode points to is embedded */ […]

C中#pragma和_Pragma()之间的区别

C中的#pragma和_Pragma()什么区别? 句法: #pragma arg 和 _Pragma(arg) 我什么时候应该使用_Pragma(arg) ?

技巧:使用宏填充数组值(代码生成)

C ++模板是伪装的宏吗? 我正在阅读上面的主题,突然想到了这个想法:为什么不尝试编写一些可以在我们的真实代码中使用的棘手宏(不仅仅是作为现实生活中无用的谜题)? 所以首先想到的是:用宏填充数组值: int f(int &i) { return ++i; } #define e100 r5(m20) #define m20 m5,m5,m5,m5 #define m5 r5(e1) #define e1 f(i) //avoiding ++i right here, to avoid UB! #define r5(e) e,e,e,e,e int main() { int i=0; //this is used in the macro e1 int a[] = {e100}; //filling array values with macros! int […]

如果未定义检查布尔宏,则生成错误

我有几个配置文件,每个配置文件包含一些布尔宏的定义,设置为0或1.然后,在我的代码中,我检查这样一个宏的值,以决定激活代码的哪一部分。 现在是棘手的部分:我想确保包含我的宏定义的标题。 在下面的示例中,如果我忘记包含包含FOO定义的头文件,编译器将打印“world!”,而我希望它生成错误。 //in the configuration header file #define FOO 1 //in a cpp file #if FOO //I would like this to generate an error if I forgot to include the header file #pragma message “Hello” #else #pragma message “world!” #endif 有可能实现这样的行为吗? 怎么样? 为了澄清,我不是问如果没有定义宏,如何生成错误 ,但是如果可以转换#if FOO行,那么同时它会检查布尔值并在FOO生成错误没有定义。 这样做的关键是开发人员会知道他们的代码应该包含 SPECIAL_MACRO(FOO) 同时,检查FOO的布尔值,好像它是#if FOO语句,并防止他们忘记包含定义FOO的头。

在引用的字符串中展开宏

可能重复: C宏来创建字符串 我有一个函数接受一个char*类型的参数,像f(“string”); 如果字符串参数是在函数调用中由the-fly定义的,那么如何在字符串体内扩展宏呢? 例如: #define COLOR #00ff00 f(“abc COLOR”); 相当于 f(“abc #00ff00″); 但是不执行扩展,函数接收字面上的abc COLOR 。 特别是,我需要将宏扩展为\”#00ff00\” ,以便将引用的标记与传递给f()的其余字符串参数连接起来,包括引号; 也就是说,预处理器必须完成他的工作并欢迎编译器从f(“abc COLOR”);转换代码f(“abc COLOR”); 到f(“abc \”#00ff00\””);

C语言中不同宏function/内联方法的优缺点

根据C FAQ ,基本上有3种用于在C中“内联”代码的实用方法: #define MACRO(arg1, arg2) do { \ /* declarations */ \ stmt1; \ stmt2; \ /* … */ \ } while(0) /* (no trailing ; ) */ 要么 #define FUNC(arg1, arg2) (expr1, expr2, expr3) 为了澄清这一点,参数在表达式中使用,逗号运算符返回最后一个表达式的值。 要么 使用inline声明作为gcc的扩展和c99标准支持 。 do { … } while (0)方法在Linux内核中被广泛使用,但是如果有的话,我还没有经常遇到其他两种方法。 我指的是多语句“函数”,而不是像MAX或MIN这样的单语句。 每种方法的优点和缺点是什么,为什么你会在各种情况下选择一种方法呢?

如何找到一些宏的来源

定义宏有很多地方。当宏在我们自己的项目中定义时,很容易找到它们的定义位置。 但是,当我尝试学习一些着名的开源项目时,我经常被这个问题所困扰:在哪里找到宏的来源,如果我不能得到它的定义,我将无法理解它们中的一些(例如其中一些可以猜到他们的名字)。 例如,来自apache的一些声明: #if defined(__osf__) && defined(__alpha), #elif defined(__NSIG) 据我所知,我知道宏有一些可能的起源地: 来自这个项目本身,在一些源文件中(这是最简单的,因为我们可以通过一些工具找到它) 从某些第三个lib的头文件中,我们可以grep它 来自c / c ++标准头文件(它们在linux中的哪个位置?) 来自os(他们在Linux中的位置?) 由配置工具自动生成(它很苦,我不知道) 从gcc / g ++这样的编译工具,或者在makefile中我们可以定义一些宏 我有一些问题需要咨询: 如何区分os定义和gcc / g ++定义和配置工具生成的宏?它们分别具有一些特征吗? 如何找到os或标准C或编译器定义的源代码? 例如,使用grep或find实用程序 如果通过梳理整个机器( cd /;grep __strange___ -r )找不到像__strange___这样的宏,这是什么意思? 感谢您告诉原则和方法来区分它们,并找到它们的来源!

宏观扩张的奇怪结果

请考虑以下代码段 #include #define A -B #define B -C #define C 5 int main() { printf(“The value of A is %d\n”, A); return 0; } 产量 The value of A is 5 但这根本不应该编译,因为在扩展后它应该看起来像printf(“The value of A is %d\n”, –5); 然后它应该给出编译错误说lvalue required。 不是吗?

在Objective-C / C中,你能编写一个结合了2个块的函数吗?

我经常发现自己创建了一个“包装器”块,它只用于执行许多其他块,通常具有相同类型的签名。 假设我有2个具有相同类型签名的块: MyBlockT block1 = ^(NSString *string, id object) { //1 does some work }; MyBlockT block2 = ^(NSString *string, id object) { //2 does some other work }; 有没有办法实现魔术函数Combine() ,它需要2个块: MyBlockT combinedBlock = Combine(block1, block2); //hypothetical function 并等同于: MyBlockT combinedBlock = ^(NSString *string, id object) { block1(string, object); block2(string, object); }; 我知道这只对返回void块有意义,但这就是我感兴趣的全部内容。 Combinefunction只需要2个块,如果我有更多,我可以链接它们。 我对于如何实现这个问题或者是否可能实现这个问题有所了解。 […]