C/C++ macros instead of const
C/C++ macros instead of const
宏#define MAX 80
与const int MAX = 80;
等价,两者都是常量,不能修改。
是不是使用宏而不是常量整数更好?常量整型占用内存。预处理器将宏的名称替换为它的值,对吗?所以它不会占用内存。
为什么我要使用const int而不是宏?
原因#1:作用域。宏完全忽略作用域。
namespace SomeNS {
enum Functor {
MIN = 0
, AVG = 1
, MAX = 2
};
}
如果上述代码恰好包含在MAX
宏定义后的文件中,它将愉快地被预处理为80 = 2
,并且编译失败。
此外,const
变量是类型安全的,可以用常量表达式安全地初始化(不需要括号)等。
还要注意,当编译器在使用const
变量时访问它的定义时,它被允许"内联"它的值。所以如果你从不取它的地址,它甚至不需要占用空间
实际上有以下几个原因:
-
作用域:你不能定义一个宏的作用域。它存在于全球范围,仅此而已。因此,你不能有特定于类的常量,你不能有私有常量,等等。此外,如果您最终声明了与您甚至不知道存在的宏同名的内容(在某些lib/header中您包含了f.e),则可能会导致名称冲突
-
调试:由于预处理器只是用其值替换宏的实例,因此要知道为什么您得到特定值的错误(或者只是您没有预料到的特定行为…)可能会变得棘手。你必须记住这个值是从哪里来的。在可重用代码的情况下,它甚至更重要,因为你甚至不知道一个值来自哪里,如果它被定义为一个宏在一个头你没有写(因此它不是很好自己做这个)
-
addresses : const变量也是一个变量。这意味着你可以传递它的地址(当需要const指针或const引用时),但是你不能使用宏
-
类型安全:您可以为const变量指定类型,而不能为宏指定类型。
作为一般规则,我想说(在我看来),当你有一个明确的选择(即const变量,枚举,内联)时,你应该避免#define
指令。
问题是它们不一样。宏只是预处理器的文本替换,而const
是一个普通变量。
如果有人试图在一个函数(如const in MAX = 32;
)中影子MAX
,当MAX
是一个宏时,他们会得到一个非常奇怪的错误消息。
在c++中,语言惯用的方法是使用常量而不是宏。试图节省几个字节的内存(如果节省的话)似乎不值得在可读性上付出代价。
1)调试对我来说是主要的。调试器很难在运行时将MAX
解析为该值,但可以使用const int
版本。
2)使用#define无法获得任何类型信息。如果你使用的是基于模板的函数;比如std::max
,你的另一个数据是const int
,那么宏版本将失败,但const int
版本不会。要解决这个问题,你必须使用#define MAX 80U
,这是丑陋的。
3)你不能用#define来控制作用域;它将应用于#define语句之后的整个编译单元。