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