我正在编写一些特定于硬件的代码,我想使用C宏,宏定义将是这样的: -
#define VALIDATE_RESOURCE_AND_ALLOCATE(MODE,RESOURCE1) if(a[MODE][RESOURCE1] != x1) || \
(a[MODE][RESOURCE1] != y1)) \
a[MODE][RESOURCE1]=x3;
因为有时我可以分配超过1个资源,例如: -
#define VALIDATE_RESOURCE_AND_ALLOCATE_1(MODE,RESOURCE1,RESOURCE2) if(a[MODE][RESOURCE1] != x1) || \ (a[MODE][RESOURCE1] != y1)) \ a[MODE][RESOURCE1]=x3; if(a[MODE][RESOURCE2] != x1) || \ (a[MODE][RESOURCE2] != y1)) \ a[MODE][RESOURCE2]=x3;
有没有办法可以编写一个宏,它涵盖了两种情况,因为它需要可变数量的参数?
我在printf宏的宏中使用了可变数量的参数,但是我将如何通过它们各自的名称来解决这些参数,例如,如果我修改MACRO定义,例如:0 -
#define VALIDA_RESOURCE_AND_ALLOCATE(MODE,.....)
我如何识别RESOURCE1,RESOURCE2?
答案 0 :(得分:1)
你的宏中有很多重复的代码。简化它们有助于使解决方案更加明显:
#define VALIDATE_RESOURCE_AND_ALLOCATE_1(MODE,RESOURCE1,RESOURCE2) do {\
VALIDATE_RESOURCE_AND_ALLOCATE(MODE, RESOURCE1); \
VALIDATE_RESOURCE_AND_ALLOCATE(MODE, RESOURCE2); \
} while(0)
在这里,更简单的是,这只是在迭代参数列表时重复调用第一个宏。
假设您知道此处使用的数据类型将始终保持一致,您可以尝试这样的事情(未经测试并写下我的头脑):
#ifdef HARDWARE_PLATFORM_A
static sometype args[] = {
RESOURCE1,
RESOURCE2,
/* ... etc, etc */
};
#elif defined HARDWARE_PLATFORM_B
static sometype args[] = {
RESOURCE10,
RESOURCE11,
/* ... etc, etc */
};
/* repeat for all hardware platforms */
#endif
void initialization_function (void) {
int i;
for (i = 0; i < (sizeof(args) / sizeof(args[0])); ++i) {
VALIDATE_RESOURCE_AND_ALLOCATE(MODE, args[i]);
}
}
其中sometype
是您将用于RESOURCE1
,RESOURCE2
等的参数的数据类型。
考虑到你要做的事情的复杂性,你在写一个函数来做迭代而不是宏时要好得多。您仍然可以使用宏来创建RESOURCE
列表,但不要尝试让预处理器为您执行迭代。如果您需要避免函数调用的开销(因为您将其标记为“嵌入”),您可以声明函数inline
,结果应该与使用宏一样有效。但是,在此过程中,您将获得类型安全等内容。
虽然技术上可能可能使用宏执行此操作,但这将是一个令人讨厌的黑客行为,最有可能带来更多问题而非利益。使用预处理器执行复杂的程序任务很少结果很好。
另一种替代方法是使用代码生成器从文件中获取RESOURCE
个参数列表,并生成包含初始化代码的.c文件。代码生成器将使用比C预处理器更强大的语言编写(这里几乎可以使用任何脚本语言)。除非你有一长串的RESOURCE
,否则这可能不值得。
答案 1 :(得分:0)
你可以实现它的一种方法是不传入可变数量的参数,但坚持使用两个参数,并使第二个参数成为可以在初始化中使用的列表。例如(为清晰起见,尾部留下反斜杠):
#define VALIDATE_RESOURCE_AND_ALLOCATE(MODE, LIST)
{
int resources[] = LIST;
int count;
for(count = 0; count < sizeof(resources)/sizeof(int); count++) {
/* do stuff here for each resources[count] */
}
}
然后你可以简单地称它为:
VALIDATE_RESOURCE_AND_ALLOCATE(MODE, { RESOURCE1, RESOURCE2 } )
注意:有一种方法可以给这只猫上皮,所以选择你喜欢的答案然后继续: - )
答案 2 :(得分:0)
这会太傻了吗? ; - )
#define VALIDATE_RESOURCE_AND_ALLOCATE(MODE,RESOURCE1,RESOURCE2) \
if(a[MODE][RESOURCE1] != x1) || (a[MODE][RESOURCE1] != y1)) \
a[MODE][RESOURCE1]=x3; \
if((RESOURCE1 != RESOURCE2) && (a[MODE][RESOURCE2] != x1) || (a[MODE][RESOURCE2] != y1))) \
a[MODE][RESOURCE2]=x3;
并将其称为单个资源
VALIDATE_RESOURCE_AND_ALLOCATE(M1,R1,R1)
,如下两个?
VALIDATE_RESOURCE_AND_ALLOCATE(M1,R1,R2)