Tag: macros

怀疑linux中的container_of宏

为什么我们使用container_of宏? container_of(pointer, container_type, container_field); 据LDD说 “这个宏在一个类型为container_field的结构中接受一个名为container_field的字段的指针,并返回一个指向包含结构的指针”。 我的问题是: 如果我们想要一个指向结构的指针(即container_type),我们可以直接分配,对吧? 那为什么其中一个字段的指针被用来为整个结构分配地址? 任何人都可以用一个例子解释使用该宏的优势吗?

使用(void *)作为通用数据容器时的L值问题

这是程序中使用的结构: struct basic_block { void * aux; /* Many other fields, which are irrelevant. */ }; 现在: 在程序执行期间存在几个basic_block实例。 该程序分阶段/通过,一个接一个地执行。 aux字段用于在阶段执行期间存储stage和basic_block特定数据,并由阶段本身释放(因此下一阶段可以重用它)。 这就是为什么它是一个void * 。 我的舞台使用aux来存储一个struct ,所以每次我想访问某些东西时,我都要做一个强制转换: ( (struct a_long_struct_name *) (bb->aux))->foo_field = foo; 现在,我的问题:每次像这样投下它是一种痛苦,当它是更复杂的表达式的一部分时难以阅读。 我建议的解决方案是:使用宏为我做演员: #define MY_DATA(bb) \ ( (struct a_long_struct_name *) (bb)->aux) 然后我可以访问我的数据: MY_DATA(bb)->foo_field = foo; 但是:我不能将MY_DATA(bb) 本身用作L值(对于malloc ),所以我使用该宏并不是一个好主意: /* WRONG! I cannot assign to […]

如何在c中清除这个lint警告?

我有以下代码: #define NUMBER_OF_ROOMS if((unsigned int)(NUMBER_OF_ROOMS – 2) > 20) { // do something here } 但是我得到了一个lint警告: Warning 506: Constant value Boolean ,这是什么意思以及如何修复它?

main.c中定义的宏在另一个包含的文件中不可见

我有多个C和H文件 在main.c我定义了一个宏,在ws_driver.c我想使用它。 ws_driver.h包含在main.c 。 main.c中 #define WS_PORT PORT_D8 #define WS_BIT D8 #define WS_DDR DDR_D8 #include “ws_driver.h” 在ws_dirver.c我有两个检查: ws_driver.c #include “ws_driver.h” #ifndef WS_PORT # error “WS_PORT not defined!” #endif #ifndef WS_BIT # error “WS_BIT not defined!” #endif 两者都失败了。 $ avr-gcc -std=gnu99 -mmcu=atmega328p -DF_CPU=16000000UL -Os -I. -I -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wno-main -Wno-strict-prototypes -Wno-comment -g2 […]

是getchar()和putchar()函数还是宏?

我提到了两个可靠的信息来源,两者似乎对同一事物有不同的定义: http://www.cplusplus.com/reference/clibr%E2%80%A6 http://www.ocf.berkeley.edu/~pad/tigcc/doc/html/stdio_fputchar.html 第一个来源说putchar()是一个函数,就像getchar() ,但在第二个链接中它表示putchar()是一个宏。 我的书说getchar()是一个宏。 哪个是对的?

变体宏:粘贴标记的扩展

我想知道是否可以“嵌套”可变宏调用。 我只关心GCC和Clang。 我的宏定义如下所示: /** * @brief Invoke an instance method. */ #define $(obj, method, …) \ ({ \ typeof(obj) _obj = obj; \ _obj->interface->method(_obj, ## __VA_ARGS__); \ }) 我用它在我的OO框架中方便地调用“实例方法”( https://github.com/jdolan/objectively ): $(array, addObject, obj); 工作老板。 不幸的是,我还没有想出一种允许嵌套这些调用的方法,这在某些情况下非常有用; 例如: /** * @see MutableSetInterface::addObjectsFromArray(MutableSet *, const Array *) */ static void addObjectsFromArray(MutableSet *self, const Array *array) { if […]

是否有一个C预处理器宏来打印结构?

据我所知,没有办法在C中打印出一个struct值。 即,这不会飞: typedef struct { int a; double b; } stype stype a; aa=3; ab=3.4; printf(“%z”, a); 相反,你必须说: printf(“a: %d\n”, aa); printf(“b: %f\n”, ab); 这似乎是一个完美的地方,你可以使用宏来保存任意结构的大量输入。 C预处理器是否足以执行此转换?

在无法识别##的编译器上吞并可变宏中的逗号

我需要在C中编写一个variadic宏,它必须带有零个或多个参数。 在gcc中,可以通过在逗号后添加“##”来实现,例如,##____VA_ARGS____在Variadic宏中以零参数的forms回答。 但是,我的构建系统中的编译器(超出我的控制范围)不理解,##语法,因此不会吞下逗号。 我可以使用一种解决方法吗? 谢谢!

用Clang的嵌套函数重写GCC清理宏?

我正在尝试解决第三方库中的问题。 问题是库使用GCC嵌套在宏中的嵌套函数,并且Clang不支持嵌套函数,并且没有计划这样做(参见, Clang Bug 6378 – 错误:函数上的非法存储类 )。 这是我和Clang痛点的宏观: #define RAII_VAR(vartype, varname, initval, dtor) \ /* Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774 */ \ auto void _dtor_ ## varname (vartype * v); \ void _dtor_ ## varname (vartype * v) { dtor(*v); } \ vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval) 以下是它的使用方法(来自代码注释): * void do_stuff(const char […]

标题的宏定义,放置它们的位置?

在定义标头所依赖的宏时,例如_FILE_OFFSET_BITS , FUSE_USE_VERSION , _GNU_SOURCE等等,放置它们的最佳位置在哪里? 我考虑过的一些可能性包括 位于依赖于该文件中包含的标头所公开的定义的任何源文件的顶部 紧接着相关标题的包含之前 通过编译器定义CPPFLAGS级别? (例如-D_FILE_OFFSET_BITS=64 ): 整个源代码回收 整个项目 只是需要它的来源 在项目标题中,还应包括宏应用的那些相关标题 其他一些我没有想过的地方,但是无限优越 注意:适用于制作,自动工具和其他构建系统的合理性是我决定的一个因素。