将常量变量定义为使程序更小吗?

时间:2014-12-25 01:18:07

标签: c++ constants c-preprocessor

示例:

#define Var1 35
static const int Var1( 35);

因此,虽然#define替换了我在编译时使用Var135的所有地方(我认为编译时间稍长,如果你有很多,因为它解析代码),使用static const int使编译器将其视为变量。

这是否意味着在使用static const int时它会增加我的程序的内存印记,因为它必须为所有这些常量使用内存,或者这个开销是否已经被编译器优化了?

我问的原因是因为我想知道在这样的情况下,在调试模式下将它们设置为static const int是否更好(所以你可以在调试时轻松查看值)但是使它们#define处于释放模式,这样可以缩小程序。

4 个答案:

答案 0 :(得分:4)

使用宏来“缩小程序”是有道理的,原因如下:

  • 使用宏可能会使程序变大或无效。
  • 宏不遵循C ++中的范围规则。您可能会无意中更换文本。
  • 根据工具的质量,您可能会丢失调试信息。
  • 如果发生有利影响,则是有限的。
  • 避免宏名称冲突的常见惯例,即 ALL UPPERCASE ,是一个眼睛。

简而言之,这是过早优化的一个例子。

正如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.