Tag:

宏调用函数

我需要一个宏(或一个函数,但最好是一个宏),它接受一个函数名和无限数量的参数,然后将参数传递给函数。 我们假设这个宏是MACROFOO 。 #define MACROFOO(function, …) /* what do I put here?? */ int foo_bar(int x, int y) { // do stuff } int main(void) { int x = 3; int y = 5; MACROFOO(foo_bar, x, y); // calls foo_bar(x, y) } 我怎么能定义这样一个宏? 我想做的事情如下: #define MACROFOO(function, args…) (function)(args) 但看起来它传递给函数,而不是实际的参数。 我该怎么办?

循环并将数据分配给结构成员的宏错误地将结构成员识别为指针

我的问题是atoi正在将字符串的hex内存地址转换为十进制,而不是字符串中包含的内容。 它是在宏中执行此操作。 当宏定义使它成为int时,为什么将struct-> member解释为指针? 下面的伪代码: if (struct.member == int)? struct.member = atoi(data) : struct.member = data; 该程序的这一部分的目的是从包含有关结构属性的信息的.csv文件中检索数据。 我可以接受一个“id”并将每个单元格字符串存储到一个字符串数组(csvRowSplit)中。 但是,我想将数组的内容传输到包含不同数据类型的结构(我想用来检索玩家保存的属性,攻击方法,商店物品等的方法)。 硬编码很容易: opponent->att = atoi(csvSplitRow[0]); opponent->= atoi(csvSplitRow[1]); opponent->hitpoints = atoi(csvSplitRow[2]); opponent->description = csvSplitRow[3]); 然而,这种结构成分更多,并且不是非常灵活或可重复。 我已经定义了一个宏来循环遍历结构的元素,并将csvSplitRow []与变量配对,如果需要转换为atoi。 #define X_FIELDS \ X(char*, description, “%s”) \ X(int, xpreward, “%d”) \ X(int, att, “%d”) \ /* … */ X(int, crit, “%d”) […]

预处理器宏将hex字符串转换为字节数组

我在我的IDE中定义了一个AES-128密钥作为构建符号,因此它像这样调用GCC: arm-none-eabi-gcc -D”AES_KEY=3B7116E69E222295163FF1CAA1681FAC” … (相当于#define AES_KEY 3B7116E69E222295163FF1CAA1681FAC ) 优点是相同的符号也可以作为参数自动传递给构建后的CLI脚本,该脚本使用此密钥加密编译的代码(例如,用于安全的固件更新)… 但是如何在代码中将此键存储为字节数组? 我想定义一个执行转换的预处理器宏: uint8_t aes_key[] = { SPLIT_MACRO(AES_KEY) }; 至 uint8_t aes_key[] = {0x3B, 0x71, 0x16, 0xE6, 0x9E, 0x22, 0x22, 0x95, …}; 换句话说,GCC预处理器是否可以在2-char块中拆分密钥字符串并在它们之间添加“ , 0x ”?

是什么导致“警告:条件表达式中的指针/整数类型不匹配”?

我有一个枚举,一个宏定义和一个所有使用枚举的方法。 我无法编译。 请考虑以下代码段。 typedef enum fruits_t { APPLE, ORANGE, BANANA } fruits_t; #define KEY_TO_VALUE(x) ((x == APPLE) ? 0 : \ (x == ORANGE) ? 1 : \ (x == BANANA) ? 2 : \ “Undefined”) static void foo(char fruit) { if (fruit == KEY_TO_VALUE(APPLE)) { /* do something */ } } 编译,但我得到以下警告。 warning: pointer/integer […]

for loop宏编码风格

我在大学的一位导师建议使用宏来减少c99代码中的重复,就像这样。 #define foreach(a, b, c) for (int a = b; a < c; a++) #define for_i foreach(i, 0, n) #define for_j foreach(j, 0, n) #define for_ij for_i for_j 哪个可以这样使用: for_ij { /*do stuff*/; } for_i { /*do stuff*/; } 另一位具有工业背景的导师不鼓励使用它,声称它被视为他前雇主的反模式(但他不知道背后的原因)。 实际上,通过浏览大型项目的源代码,很少能够在简短的学术范例之外找到这些结构。 我的问题是:为什么这种结构在实践中很少使用? 它在某种程度上是危险的吗?

是否有可能防止C中宏的重复,相同的参数?

在某些罕见的情况下,防止宏的重复参数可能很有用。 拿这个ELEM(value, …)宏, 检查value是A , B还是C if (ELEM(value, A, B, C)) { …. } 有人可能偶然会多次传入相同的参数,例如: if (ELEM(value, A, B, B)) { …. } 虽然有效的C,但几乎肯定是一个意外,并且极不可能是开发人员的意图。 ……这当然是一个微不足道的例子,实际的错误案例会更复杂。 题 有没有办法让编译器发出警告/错误 传递重复参数时? 澄清: 参数不一定是所有常量(它们也可以与变量混合)。 笔记… 问,因为这是我最近在一些代码中发现的实际错误。 虽然有限制宏/编译器可以防止出错,但如果宏不允许,可能会提前检测到。 当然这些错误应该在代码审查中找到…… 然而,错误发生了。 这可能必须使用一些GCC /编译器特定的扩展,例如__builtin_constant_p 。 执行此操作的一种方法(这不是简单的certificate,但有助于避免一些错误) ,可能是将标识符转换为字符串,然后静态断言,如果任何标识符是完全匹配。 具有明显的缺点,即不同的标识符可以表示相同的常数值。 也可以写入相同的标识符以便不进行比较,例如: A[0]对A[ 0 ] 。 如果预处理器/编译器不能轻易地做到这一点,那么后退解决方案可能是做一些基本的静态检查工具。

为C / C ++编写一个宏#include

我在AS / 400上工作,有时候是非POSIX。 我们还需要在UNIX上编译我们的代码。 我们遇到像#include这样简单的问题。 在AS / 400上,我们需要写: #include“* LIBL / H / MYLIB” 在UNIX上,我们需要编写 #include“MYLIB.H” 目前我们在每个C / C ++文件的顶部都有这个(丑陋的)块: #ifndef IS_AS400 #include“* LIBL / H / MYLIB” / *其他人在这里* / #其他 #include“MYLIB.H” / *其他人在这里* / #万一 我们想要一个统一的宏。 这可能吗? 我不知道怎么写。 理想情况下,生成的语法将是: SAFE_INCLUDE( “MYLIB”) 这将在每个平台上正确扩展。 请指教。

ISO C等同于表达式中的支撑组

如何以兼容(ISO C99)方式执行以下操作? #define MALLOC(type, length, message) ({ \ type * a_##__LINE__ = (type *)malloc((length) * sizeof(type)); \ assert(message && (a_##__LINE__ != NULL)); \ a_##__LINE__; \ }) double **matrix = MALLOC(double *, height, “Failed to reserve”); 注意:要编译我使用:gcc -std = c99 -pedantic …

Emacs在C中的宏后缩进

#define INIT_MACRO create(); some(); enviroment(); … void function(){ INIT_MACRO extra_indented(); normal_indented(); } 当请求自动缩进时,如何使emacs正确处理上述情况? 编辑我看到的唯一解决方案是告诉emacs处理仅包含大写字母,下划线和空格的行,就好像他们最后有分号一样……但我该怎么做?

__DATE__宏的格式不同

C有一个预定义的宏__DATE__ ,它显示已编译源文件的日期。 日期以“Mmm dd yyyy”格式显示。 有没有办法使用宏格式化这个日期? 以这种格式“yyyy Mmm dd” 。 而不是: 2013年7月19日 应该 : 2013年7月19日