示例:
#define Var1 35
static const int Var1( 35);
因此,虽然#define
替换了我在编译时使用Var1
和35
的所有地方(我认为编译时间稍长,如果你有很多,因为它解析代码),使用static const int
使编译器将其视为变量。
这是否意味着在使用static const int
时它会增加我的程序的内存印记,因为它必须为所有这些常量使用内存,或者这个开销是否已经被编译器优化了?
我问的原因是因为我想知道在这样的情况下,在调试模式下将它们设置为static const int
是否更好(所以你可以在调试时轻松查看值)但是使它们#define
处于释放模式,这样可以缩小程序。
答案 0 :(得分:4)
使用宏来“缩小程序”是有道理的,原因如下:
简而言之,这是过早优化的一个例子。
正如Donald Knuth所说,过早的优化是邪恶的。
顺便说一句,请注意
中的static
static const int Var1( 35);
如果在命名空间范围内,... 冗余。默认情况下,命名空间范围常量具有内部链接只需写下
const int Var1 = 35;
......效果相同,但恕我直言更清楚。
答案 1 :(得分:3)
如果它是static
,那么编译器可以看到它只在该翻译单元内使用,而不必想知道它是如何在外部使用的,这是一个优点。如果你不做任何事情使它必须成为一个实际的变量(比如创建一个指向它的指针),那么编译器通常会优化它。
更友好的方法可能是使用枚举
enum { Var1 = 35 };
或在C ++ 11中,constexpr
constexpr int Var1 = 35;
这些还有一个好处就是不会在另一个范围内弄乱同名变量,如果你以后有
void f() {
int Var1;
}
#define会将其变为int 35;
但是,所使用的内存差异将非常小,可能非常小,除非您处于极其有限的环境中,否则它将永远不会对性能产生任何可衡量的影响。
答案 2 :(得分:2)
"这是否意味着在使用
static const int
时它会增加我的程序的内存印记,因为它必须为所有这些常量使用内存,或者这个开销是多少无论如何由编译器进行优化?"
这完全取决于您的实际编译器的实现,以及如何使用它完成优化功能。
对于简单数值常数的情况,在逻辑上下文中我仍然使用enum
声明。
我发现使用static const int Var1( 35);
的大部分时间都是#define
d值的最佳选择,因为我可以完全控制应该看到的范围。
答案 3 :(得分:1)
每个体面的编译器都会进行常量传播,以查看哪个表达式保持不变。 const
帮助编译器完成这项工作。
大多数编译器接下来要做的就是删除代码中未使用的部分。这就是为什么外部不可见的const
变量(局部变量,静态变量)或间接变量(即变量的地址未被用作为指针赋值的参考)被删除的原因由优化器。
示例:
static const int e = 29;
int main()
{
int x = e;
return x + 1;
}
将由MSVC 2013在发布模式下编译为:
PUBLIC _main
_TEXT SEGMENT
_main PROC
mov eax, 30 ; optimized the code to return 30
ret 0
_main ENDP
_TEXT ENDS
END ; no place is reserved nowhere for the static.