[英]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.