代码之家  ›  专栏  ›  技术社区  ›  Synetech

在C++中移除未使用的(未引用的)静态全局变量常量

c++
  •  2
  • Synetech  · 技术社区  · 16 年前

    使现代化 ,




    我有一个头文件,其中包含一些常用常量,如名称和内容,这些常量会自动包含在每个项目中(下面是一个示例)。问题是,无论是否使用(引用)它们,它们都包含在已编译的二进制文件(EXE)中。如果我使用DEFINEs,那么如果不使用,它们自然不会被包括在内,但是const当然比DEFINEs好,所以我试着用谷歌搜索它,但我能找到的最接近的东西是 a question 就在这里,所以没什么帮助。撇开i18n的问题不谈,我怎样才能在保持易用性的同时,将未使用的保留在二进制之外呢?

    谢谢


    //COMMON.H:
      static const CString s_Company _T("Acme inc.");
      //etc. others
      static const CString s_Digits  _T("0123456789");
    
    //TEST.CPP:
      #include common.h
      int main() {
        AfxMessageBox(s_Company);
      }
    
      //s_Company should be in the final EXE, but s_Digits should not be, but is
    
    4 回复  |  直到 9 年前
        1
  •  2
  •   Adam Rosenfield    16 年前

    它们没有从二进制文件中剥离的原因是它们 使用: CString 不是POD类型,因此当您在全局范围内创建它们的实例时,编译器必须生成代码来调用它们的构造函数和析构函数。

    const TCHAR*

    static const TCHAR *s_Company = _T("Acme inc.");
    static const TCHAR *s_Digits  = _T("0123456789");
    

    然后,编译器将自动从二进制文件中删除未使用的常量。但是,需要记住的一点是,如果字符串在多个文件中使用,那么二进制文件中将包含这些字符串的多个副本,使用该字符串的每个翻译单元都有一个副本。甚至连gcc都没有 -fmerge-constants extern 声明,然后将字符串常量的值放入源文件中(通常在一个文件中,但这不是必需的)。这还允许您更改常量,而无需重新编译使用它们的每个文件。

        2
  •  1
  •   Donal Fellows    16 年前

    extern const CString s_Company;
    

    const CString s_Company _T("Acme inc.");
    

    然后你只能链接你需要的常量;链接器将在其错误消息中告诉您是否缺少任何链接!(还有一些方法可以告诉编译器不要在构建的库中公开这些符号,假设您正在构建库,但它们不是标准的或可移植的。)

        3
  •  0
  •   Zoli    16 年前

    如果定义了明确的规则以明确何时要使用what,则可以使用如下预处理器定义:

    #if defined CONFIG_COMPANY
      static const CString s_Company _T("Acme inc.");
    #elif defined CONFIG_DIGITS
      static const CString s_Digits  _T("0123456789");
    #endif
    

    然后,您可以在单独的配置标头中定义或不定义这些值。

    顺便说一下,如果这个文件要包含在许多源文件中,那么您应该避免将这些常量声明为 static . 它们具有内部链接,您将在所有翻译单元中获得它们的单独副本。

        4
  •  0
  •   Lance Diduck    16 年前

    http://msdn.microsoft.com/en-us/library/a44fb3wy(VS.80).aspx )

    在您的例子中,有两个常量cstring,因此资源编译器将生成如下内容

    #define IDS_COMPANY 1
    #define IDS_DIGITS  2
    

    因此,在本例中,您将有一个带有两个字符串的.dll。您的应用程序将加载.dll(AfxLoadLibrary)。然后,当您需要字符串时,应用程序会从resource.dll加载该字符串。

    这就是防止Windows应用程序因全局静态字符串、位图等而膨胀的原因。