C 宏中参数的变量号
我正在编写一些特定于硬件的代码,我想在其中使用 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[模式][资源1]!= y1)) \ a[模式][资源1]=x3; if(a[模式][资源2] != x1) || \ (a[模式][资源2]!= y1)) \ a[模式][资源2]=x3;
有什么方法可以编写一个涵盖这两种情况的宏,因为它需要可变数量的参数?
我在 printf 宏的宏中使用了可变数量的参数,但是我将如何通过它们各自的名称来寻址这些参数,例如,如果我修改宏定义,例如:0-
#define VALIDA_RESOURCE_AND_ALLOCATE(MODE,.....)
我将如何识别 RESOURCE1、RESOURCE2?
I am writing some hardware specific code, where I want to use C Macros, the macro definition would be something like this:-
#define VALIDATE_RESOURCE_AND_ALLOCATE(MODE,RESOURCE1) if(a[MODE][RESOURCE1] != x1) || \
(a[MODE][RESOURCE1] != y1)) \
a[MODE][RESOURCE1]=x3;
Since sometimes I can have more then 1 resource to allocate, such as:-
#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;
Is there any way I can write a macro, which covers both cases, as it takes variable number of arguments?
I have used variable number of arguments, in macro for printf macros, but then how I will address those arguments, by their respective name, for example, if I modify the MACRO definition such as:0-
#define VALIDA_RESOURCE_AND_ALLOCATE(MODE,.....)
How will I identify RESOURCE1, RESOURCE2?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的宏中有很多重复的代码。简化它们有助于使解决方案更加明显:
在这里,更清楚的是,这只是在迭代参数列表时重复调用第一个宏。
假设您知道此处使用的数据类型始终是一致的,您可以尝试这样的操作(未经测试并在我的脑海中写下来):
其中
sometype
是参数的数据类型您将用于RESOURCE1
、RESOURCE2
等。考虑到您想要做的事情的复杂性,您最好编写一个函数来执行迭代而不是宏。您仍然可以使用宏来创建 RESOURCE 列表,但不要尝试让预处理器为您执行迭代。如果您需要避免函数调用的开销(因为您将其标记为“嵌入”),则可以将函数声明为内联,结果应该与使用宏一样高效。不过,在此过程中,您将获得诸如类型安全之类的东西。
虽然从技术上来说可以用宏来做到这一点,但这将是一种令人讨厌的黑客行为,很可能会带来更多的问题而不是好处。使用预处理器执行复杂的程序任务很少会取得好的结果。
另一种选择是使用代码生成器,该生成器从文件中获取 RESOURCE 参数列表,并生成包含初始化代码的 .c 文件。代码生成器将使用比 C 预处理器更强大的语言编写(几乎可以使用任何脚本语言)。不过,除非您有很长的 RESOURCE 列表,否则这可能不值得。
Your macros have a lot of repeated code in them. Simplifying them helps make a solution more apparent:
Here, it's clearer that this is simply a repeated invocation of the first macro while iterating through a list of arguments.
Assuming you know that the data types being used here will always be consistent, you can try something like this (untested and written off of the top of my head):
where
sometype
is the data type of the arguments that you will be using forRESOURCE1
,RESOURCE2
, etc.Given the complexity of what you are trying to do, you'd be a lot better off writing a function to do the iteration instead of a macro. You can still use a macro to create the
RESOURCE
list, but don't try to get the pre-processor to do the iteration for you. If you need to avoid the overhead of a function call (since you tagged this as 'embedded'), you can declare the functionsinline
and the result should be as efficient as using a macro. In the process, though, you'll gain things like type safety.While it might be technically possible to do this with a macro, it would be a nasty hack that would most likely bring more problems than benefits. Doing complex procedural tasks with the pre-processor rarely turns out well.
The other alternative that you have is to use a code generator that takes a list of
RESOURCE
arguments from a file and generates a .c file containing the initialization code. The code generator would be written in a language much more powerful than the C pre-processor (almost any scripting language could be used here). This probably wouldn't be worth the trouble unless you had a long list ofRESOURCE
s, though.实现这一目标的一种方法是不要传递可变数量的参数,而是坚持使用两个参数,并使第二个参数成为可在初始化中使用的列表。例如(为了清楚起见,后面的反斜杠被省略):
然后你可以简单地这样称呼它:
注意:有不止一种方法可以给这只猫剥皮,所以选择你最喜欢的答案并使用它:-)
One way you could accomplish it is don't pass in a variable number of arguments, but stick with two and make the second one be a list that can be used in an initialization. For example (trailing backslashes left off for clarity):
And then you can simply call it as such:
Note: there is more than one way to skin this cat, so pick your favorite answer and go with it :-)
这会不会太傻了? ;-)
对于单个资源,按如下方式调用
,对于两个资源,按如下方式调用?
Would this be too silly? ;-)
and Call it as below for single resource
and like below for two?