如何在C中实现通用宏?
FUNC(param);
当param
为char *
时,调度到func_string
。
当它是 int 时,调度到 func_int
我认为可能有一个解决方案,因为变量类型在编译时是已知的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
FUNC(param);
当param
为char *
时,调度到func_string
。
当它是 int 时,调度到 func_int
我认为可能有一个解决方案,因为变量类型在编译时是已知的。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(7)
这对于 C1X 是可能的,但在当前标准中是不可能的。
它看起来像这样:
This will be possible with C1X but not in the current standard.
It will look like this:
编译器知道变量类型,但预处理器不知道(预处理器将代码简单地视为
非结构化文本标记流,并且仅对其执行简单的替换操作)。所以恐怕你无法用 C 宏来实现这一点。在 C++ 中,他们发明了模板来解决此类问题(以及更多问题)。
Variable types are known to the compiler, but not to the preprocessor (which sees the code simply as
unstructured texta stream of tokens, and performs only simple replacement operations on it). So I am afraid you can't achieve this with C macros.In C++, they invented templates to solve such problems (and more).
您可以测试类型的特征。
例如,
int
可以保存负值,而char*
则不能。所以如果((typeof(param))-1)
((typeof(param))-1)
((typeof(param))-1)
0
,param
是无符号的:编译器显然对此进行了优化。
在这里尝试一下:http://ideone.com/et0v1
如果类型具有不同的大小,这会更容易。例如,如果您想编写一个可以处理不同字符大小的通用宏:
GCC 有一个
__builtin_types_兼容_p()
可以检查类型兼容性的内置函数:在这里尝试一下:http://ideone.com/lEmYE
您可以将其放入宏中以实现您想要执行的操作
:(
({...})
是一个 GCC的语句表达式,它允许一组语句作为右值。__builtin_choose_expr()
builtin 可以选择要编译的表达式。 __builtin_types_兼容_p 如果参数的类型与int
和char*
都不兼容,则允许在编译时触发错误:(通过在这种情况下编译无效的内容)实际上是 __builtin_choose_expr 文档。
You can test for the characteristics of the types.
For example,
int
can hold a negative value, whilechar*
can't. So if((typeof(param))-1) < 0
,param
is unsigned:The compiler obviously optimizes this out.
Try it here: http://ideone.com/et0v1
This would be even easier if the types had different sizes. For example, if you want to write a generic macro than can handle different character sizes:
GCC has a
__builtin_types_compatible_p()
builtin function that can check for types compatibility:Try it here: http://ideone.com/lEmYE
You can put this in a macro to achieve what you are trying to do:
(The
({...})
is a GCC's statement expression, it allows a group of statements to be a rvalue.The
__builtin_choose_expr()
builtin can choose the expression to compile. With __builtin_types_compatible_p this allows to trigger an error at compile-time if the type of param is not compatible with bothint
andchar*
: (by compiling somehting invalid in this case)This is actually a slightly modified example from __builtin_choose_expr docs.
C89 / ANSI C 中不可能运行时检查类型,但 gcc 的扩展允许这样做。 typeof 或者类似的东西,如果我记得的话。我在 Linux 内核中见过一次。
在 kernel.h 中:
看一下这篇文章: GCC Linux 内核中的黑客
当我第一次看到这个时,我实际上在这里问了一个问题:
kernel.h 中的 min 宏
我不太确定您将如何使用它来解决您的问题,但它值得一看。
There is no possibility to run time check types in C89 / ANSI C, but there is an extension to gcc which allows it. typeof or something along those lines if I remember. I saw it in the Linux Kernel once.
In kernel.h:
Take a look at this article: GCC hacks in the Linux kernel
When I first saw this I actually asked a question here on SO about:
min macro in kernel.h
I'm not quite sure exactly how you would use it to solve your problem, but it's something worth taking a look at.
你不能用宏来做到这一点。宏的值在编译时被替换并且不被解释。他们只是替代品。
You can't do this with a macro. Macro's value are substituted at compile time and are not intepreted. They are just substitutions.
变量类型确实在编译时已知,但是宏扩展在编译之前发生。我建议你实现 2 个重载函数而不是宏。
Variable types are indeed known at compile time, however macro expansion takes place before compilation. I suggest you implement 2 overloaded functions instead of a macro.
我对泛型的定义:
结构化抽象类型,只能用其他具体类型的输入来完全定义,
这听起来就像一个宏,
请原谅伪 c 代码,我的 c 生锈了
my definition of a generic:
a structured abstract type which can only be fully defined with an input of other concrete types
this sounds exactly like a macro to me
pardon the psudo c code, my c is rusty