Tag: c preprocessor

如何在C中实现动态调度表

首先,我了解如何使用函数指针和字符串或其他查找来实现调度表,这不是挑战。 我正在寻找的是在编译时动态地向该表添加条目的一些方法。 我希望的代码结构类型如下: Strategy.h – 包含调度程序和调度表定义的函数定义Strategy.c – 包含调度程序的代码 MyFirstStrategy.c – 包括Strategy.h并提供策略MyOtherStrategy.c的一个实现 – 包括Strategy.h并提供策略的第二个实现 我们的想法是,将函数指针和策略名称插入到调度表中的代码不应该存在于Strategy.c中,而应该存在于各个策略实现文件中,并且查找表应该以某种方式在编译时动态构造。 对于固定大小的调度表,这可以如下管理,但我想要一个动态大小的表,我不希望Strategy.c实现必须包含实现的所有头文件,我想要调度要在编译时构造的表,而不是运行时。 固定大小示例 Strategy.h typedef void strategy_fn_t(int); typedef struct { char *strategyName; strategy_fn_t *implementation; } dispatchTableEntry_t; MyFirstStrategy.h #include “Strategy.h” void firstStrategy( int param ); MyOtherStrategy.h #include “Strategy.h” void otherStrategy( int param ); Strategy.c #include “Strategy.h” #include “MyFirstStrategy.h” #include “MyOtherStrategy.h” dispatchTableEntry_t dispatchTable[] = […]

用于在C中连接两个字符串的宏

我正在尝试定义一个宏,假设它采用2个字符串值并返回它们之间的一个空格连接。 似乎我可以使用除了空格之外我想要的任何角色,例如: #define conc(str1,str2) #str1 ## #str2 #define space_conc(str1,str2) conc(str1,-) ## #str2 space_conc(idan,oop); space_conc将返回“idan-oop” 我想要一些东西回归“idan oop”,建议?

检测字节序

我正在尝试创建一个C源代码,无论目标系统的字节顺序如何,它都能正确处理I / O. 我选择了“little endian”作为我的I / O约定,这意味着,对于大端CPU,我需要在写入或读取时转换数据。 转换不是问题。 我面临的问题是检测字节序,最好是在编译时(因为CPU在执行过程中不会改变字节序…)。 到目前为止,我一直在使用这个: #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ … #else … #endif 它被记录为GCC预定义宏,Visual似乎也理解它。 但是,我收到报告说某些big_endian系统(PowerPC)的检查失败了。 所以,我正在寻找一个万无一失的解决方案,确保无论编译器和目标系统如何都能正确检测到字节顺序。 好吧,他们中的大多数至少…… [编辑]:提出的大多数解决方案都依赖于“运行时测试”。 编译期间编译器有时可以正确评估这些测试,因此不会产生实际的运行时性能。 但是,使用某种<< if (0) { … } else { … } >>进行分支是不够的。 在当前的代码实现中,变量和函数声明依赖于big_endian检测。 使用if语句无法更改这些内容。 嗯,显然,有后备计划,即重写代码…… 我宁愿避免这种情况,但是,它看起来像是一个越来越小的希望…… [编辑2]:我通过深度修改代码测试了“运行时测试”。 尽管他们正确地完成了工作,但这些测试也会影响性能。 我期待着,因为测试具有可预测的输出,编译器可以消除坏分支。 但不幸的是,它并不是一直有效。 MSVC是一个很好的编译器,并且成功地消除了坏分支,但GCC的结果好坏,具体取决于版本,测试类型,以及对64位比对32位的影响更大。 真奇怪。 并且这也意味着无法确保编译器处理运行时测试。 编辑3 :这些天,我正在使用编译时常量联合,期望编译器将其解析为明确的是/否信号。 它运作得很好: https : //godbolt.org/g/DAafKo

对C宏扩展和整数运算感到困惑

可能重复: 一个谜语(在C中) 关于以下代码段,我有几个问题: #include #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; } 这里代码的输出不会按预期打印数组元素。 但是当我添加一个(int)的类型转换时,ELEMENTS的宏定义为 #define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0])) 它按预期显示所有数组元素。 这种类型转换是如何工作的? 基于此,我有几个问题: 如果我有一些宏定义,这是否意味着: #define AA (-64) 默认情况下,在C中,所有定义为宏的常量都等同于signed int 。 如果是,那么 但是,如果我必须强制在宏中定义一些常量,因为unsigned int是否有任何常量后缀而不是我可以使用(我试过UL,UD既不起作用)? 如何在宏定义中定义常量以表现为unsigned int?

“#define STR(a)#a”有什么作用?

我正在阅读phoneME的源代码。 这是一个FOSS JavaME实现。 它是用C ++编写的,我偶然发现了这个: // Makes a string of the argument (which is not macro-expanded) #define STR(a) #a 我知道C和C ++,但我从来没有读过这样的东西。 #a中的#是做什么的? 此外,在同一个文件中,有: // Makes a string of the macro expansion of a #define XSTR(a) STR(a) 我的意思是,定义一个新宏有什么用,如果它只是调用一个现有的宏? 源代码位于https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view =标记 。 你可以用CTRL + F找到它。

宏和function相同的名称

我有以下代码 #define myfunc(a,b) myfunc(do_a(a), do_b(b)) void myfunc(int a, int b) { do_blah(a,b); } int main() { int x = 6, y = 7; myfunc(x,y); return 0; } 我希望预处理器只在调用时扩展函数myfunc。 预处理后所需的代码如下所示: void myfunc(int a, int b) { do_blah(a,b); } int main() { int x = 6, y = 7; myfunc(do_a(x),do_b(y)); return 0; } 问题是函数定义也像这样扩展 void myfunc(do_a(int a), […]

变异的宏伎俩

创建可变参数宏FOO(a1, a2, a3,…, an)的技巧是什么FOO(a1, a2, a3,…, an)使得它在任何预选的有界范围内扩展到FOOn(a1, a2, a3,…, an)的n值你选? 也就是说, FOO(a)应扩展到FOO1(a) , FOO(a, b, c)到FOO3(a, b, c)等。我知道有一个标准技巧但我似乎无法找到它。 请随意将此问题标记为副本,如果答案中还有其他问题,请将其关闭。 我怀疑有,但我找不到它。

C宏来创建字符串

替代标题(以帮助搜索) 将预处理程序标记转换为字符串 如何从C宏的值创建一个char字符串? 原始问题 我想使用C #define在编译时构建文字字符串。 该字符串是为调试,发布等而更改的域。 我想要一些这样的事情: #ifdef __TESTING #define IV_DOMAIN domain.org //in house testing #elif __LIVE_TESTING #define IV_DOMAIN test.domain.com //live testing servers #else #define IV_DOMAIN domain.com //production #endif // Sub-Domain #define IV_SECURE “secure.IV_DOMAIN” //secure.domain.org etc #define IV_MOBILE “m.IV_DOMAIN” 但预处理器不评估“”内的任何内容 有没有解决的办法? 这是一个好主意吗?

C宏和括号中的参数使用

例 #define Echo(a) a #define Echo(a) (a) 我意识到这里可能没有显着差异,但为什么你会想要在宏体内包含a括号内的a ? 它是如何改变它的?

宏值的字符串化

我遇到了一个问题 – 我需要使用宏值作为字符串和整数。 #define RECORDS_PER_PAGE 10 /*… */ #define REQUEST_RECORDS \ “SELECT Fields FROM Table WHERE Conditions” \ ” OFFSET %d * ” #RECORDS_PER_PAGE \ ” LIMIT ” #RECORDS_PER_PAGE “;” char result_buffer[RECORDS_PER_PAGE][MAX_RECORD_LEN]; /* …and some more uses of RECORDS_PER_PAGE, elsewhere… */ 这失败了一条关于“stray#”的消息,即使它有效,我想我会得到字符串化的宏名称,而不是值。 当然,我可以将值提供给最终方法( “LIMIT %d “, page*RECORDS_PER_PAGE ),但它既不漂亮也不高效。 当我希望预处理器不以特殊方式处理字符串并且像普通代码一样处理它们的内容时,就像这样。 现在,我用#define RECORDS_PER_PAGE_TXT “10”表达它,但可以理解的是,我对它并不满意。 如何做到对了?