使用宏而不是静态内联方法有什么显着的好处吗?特别是,如何使用静态内联方法在调用链中进一步传递varargs,这可以使用宏一步完成?
#define myprintf(fmt, args...) printf (fmt, args)
这只是一个简单的例子,但我仍然很好奇是否有使用静态内联的相同方法,而不使用va_args步骤。
编译器是否一直在内联静态内联方法?他们的体型怎么样?如何调用任意子方法?如果我使用多个宏,则所有宏都会编译成单个表达式,因此编译器可能更容易进行优化。编译器是否足够智能将多级静态内联调用转换为单个表达式?
答案 0 :(得分:3)
使用宏而不是静态内联方法有什么显着的好处吗?
宏不进行类型检查,也不评估它们的参数,这会带来巨大的威力和巨大的危险。
所以(引用一个众所周知的例子)
#define MAX(a,b) (a>b)?a:b
似乎比
更好static inline int max(a,b) { return (a>b)?a:b; }
因为它不需要int
参数(即适用于支持>
运算符的所有类型),除了
a
或b
两次(考虑MAX(a++,b++)
)这解决了第二个问题:
#define MAX(a,b) ((a)>(b)?(a):(b))
如何使用静态内联方法在调用链中进一步传递varargs,这可以使用宏一步完成?
C99支持可变参数宏,gcc
对此定义的here具有(非标准)扩展。
实际上有两种格式:
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
其中__VA_ARGS__
被可变元素替换;这是标准的C99。
gcc
还提供:
#define debug(format, args...) fprintf (stderr, format, args)
其中args
可以代表多个参数。
在第一个公式中,仅使用gcc
,您可以完全省略参数,并使用粘贴宏运算符##
避免使用多余的逗号,即:
#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
实现这一目标有no standards-based way。
[编译器] [始终]内联static inline
方法吗?
不,编译器可以自由地做它想做的事情。它可以内联它们,或者为每个编译单元生成一组目标代码。但是,至少在理论上,它可以对#define
&#d; d宏执行相同的操作。编译器不会总是将多个级别的内联宏转换为单个表达式,因为即使单个内联宏实际上也不能内联编码;通常,编译器在确定这是否是个好主意时比程序员更聪明。