“#define”和 inline 的行为是否相同?
不,他们没有!
宏和内联函数之间存在许多差异。
- 评估次数
作为参数传递给内联函数的表达式只计算一次。
在某些情况下,作为参数传递给宏的表达式可以被多次计算。每次在宏中使用参数时,都会评估该参数。
代码示例:
#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;
}
目的可能是打印 1 和 2,但宏扩展为:
int c = a++ > b++ ? a++ : b++;
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;
}
可以将字符串传递给执行一些整数运算的宏,而宏不会抱怨!
- 建议还是命令?
内联只是对编译器的建议。是否内联扩展函数由编译器决定。
宏将始终被扩展。
- 调试怎么样?
内联函数可以很容易地调试,因为您可以在内联函数定义处放置一个断点,并逐步进入调试方法。
宏不能用于调试,因为它们在预编译时被扩展。