Kai*_*ije 3 c c++ inline-functions c-preprocessor
我在我的一个标题中有一些简短的定义,如下所示:
#define ROUND_DOWN(a,b) (a)-(a)%(b)
Run Code Online (Sandbox Code Playgroud)
例如
ROUND_DOWN(178,32) = 160
Run Code Online (Sandbox Code Playgroud)
但是,如果我把它传递给它:
ROUND_DOWN(160*2, 32);
Run Code Online (Sandbox Code Playgroud)
然后它像这样编译?
(160*2)-(160*2)%(32),
Run Code Online (Sandbox Code Playgroud)
这只是处理160*2两次..
我想知道内联函数是否以相同的方式运行?例如
inline int RoundDown(int a, int b)
{
return (a)-(a)%(b)
}
Run Code Online (Sandbox Code Playgroud)
将160*2作为320存储在"int a"中,然后计算会起作用,还是它的行为与定义相同?
一个更好的例子是:
RoundDown((x+x2)*zoom, tile_width);
Run Code Online (Sandbox Code Playgroud)
"#define"和内联行为是否相同?
不,他们不!
宏和内联函数之间存在许多差异.
- 没有评估时间
作为内联函数的参数传递的表达式将被计算一次.
在某些情况下,作为参数传递给宏的表达式可以多次计算.每次在宏中使用参数时,都会评估该参数.
代码示例:
#define max(a,b) (a>b?a:b)
int main()
{
int a = 0;
int b = 1;
int c = max(a++, b++);
cout << a << endl << b << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
意图可能是打印1和2,但宏扩展为:
int c = a++ > b++ ? a++ : b++;
Run Code Online (Sandbox Code Playgroud)
b增加两次,程序打印1和3.
- 谁评估他们
内联函数由编译器评估,而预编译器在预编译时评估宏.
- 类型检查
内联函数遵循在正常函数上强制执行的所有类型安全协议.检查参数类型,并正确执行必要的转换.在将内联函数放入符号表之前,编译器执行返回类型检查,函数签名.
它们可以被重载以对正确类型的数据执行正确的操作.
与内联函数相比,宏更容易出错.参数未键入(宏适用于任何算术类型的对象).编译期间未进行错误检查.
代码示例:
#define MAX(a, b) ((a < b) ? b : a)
int main( void)
{
cout << "Maximum of 10 and 20 is " << MAX("20", "10") << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
可以将字符串传递给执行某种整数运算的宏,并且宏不会抱怨!
- 建议还是命令?
内联只是对编译器的建议.编译器决定是否内联扩展函数.
宏将永远扩展.
- 调试怎么样?
内联函数可以轻松调试,因为您可以在内联函数定义中设置断点并逐步进入调试方法.
宏不能用于调试,因为它们在预编译时扩展.
首先,您应该假设在编译时计算所有常量表达式,以便在运行程序时乘法永远不会存在.
其次,你根本不能依赖inline任何效果,它只是对编译器的暗示,而不是一个要求.
但即使函数没有内联,表达式也不会被计算两次,因为参数传递要求在函数体运行之前对其进行求值.