簡體   English   中英

extern const指針的常量正確性

[英]Const correctness for extern const pointers

我試圖定義一個常量字符串,我可以在cpp文件中使用它,以便數據和指針都不能被修改。 鏈接器抱怨以下內容:

main.obj:錯誤LNK2001:未解析的外部符號“ char const * const g_someString”

樣例代碼:

//constants.h
extern const char * const g_someString;

//constants.cpp
const char * const g_someString = "Hello";

// main.cpp
int main()
{
    strcmp(g_someString, "Hello");
}

但是,將const char * const替換為const char *時,不會發生這種情況。 編譯器(MSVC 2015)是否優化了constants.cpp中的g_someString定義?

之前

const char * const g_someString = "Hello";

您需要將其聲明為extern (例如,通過包含標頭),因為const名稱空間級別的變量默認情況下具有內部鏈接。


也就是說,您可以僅在標題中定義字符串。 單獨的編譯使您能夠修改字符串,而無需重新生成許多文件,但是除此之外,恕我直言,它是過早的優化。


為了使標頭中的字符串定義對於inline函數而言形式上安全,如果需要的話,您需要使字符串(或至少是指針)具有extern鏈接。 一種方法是在“一個定義規則”中利用模板的特殊豁免。 例如:

// Perhaps best generated by some code generation facility:
template< class Dummy >
struct Strings_
{
    static char const* const some_string;
    static char const* const some_other_string;
};

template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Blah!";

template< class Dummy >
char const* const Strings_<Dummy>::some_string = "Oh, well.";

using Strings = Strings_<void>;

然后用法

inline void foo() { cout << Strings::some_string << endl; }

這里的Strings::some_string指針在所有翻譯單元中都相同。

另一種方法是在內inline函數中定義字符串。 然后,您可以使用例如枚舉來命名它們。

enum String_id { some_string, some_other_string };

inline
auto strings( String_id const id )
    -> char const*
{
    switch( id )
    {
    case some_string:          return "Blah!";
    case some_other_string:    return "Oh, well.";
    }
    assert( false );    // Should never get here.
}

使用像

inline void foo() { cout << strings( some_string ) << endl; }

inline函數具有extern鏈接,因此在所有翻譯單元中都相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM