[英]Visual Studio 2012 __cplusplus and C++ 11
任何人都知道為什么__cplusplus
在我的 Visual Studio 2012 c++ 項目中被定義為199711L
(這是“舊”C++)? 自從VS 2012現在支持C ++ 11以來,不應該說201103L
嗎? 即使我包含 C++ 11 頭文件,它仍然是錯誤定義的。 有什么線索嗎?
這已提交給 Microsoft 進行審核:
這實際上取決於您期望該宏的實際含義。 201103L 是否應該表示“此編譯器完全支持編譯器和庫中的所有 C++11?” 它應該意味着“這個編譯器支持一些合理的 C++11 子集嗎?” 是否應該表示“此編譯器以某種方式、形狀或形式支持至少一個C++11 功能?”
真正取決於每個實現來決定何時增加版本號。 Visual Studio 與 Clang 和 GCC 不同,它沒有單獨的 C++03 編譯模式; 它提供了一組特定的功能,這就是它所提供的。
通常,單個宏不是決定何時使用某些功能的有用工具。 Boost.Config是一種更可靠的機制。 標准委員會正在研究在標准的未來版本中處理這個問題的方法。
我和尼科爾在這件事上。 測試__cplusplus >= 201103L
的唯一原因是檢查您是否可以使用新功能。 如果編譯器只實現了一半的新特性但使用__cplusplus
的新值,它將無法編譯許多受__cplusplus >= 201103L
保護的有效 C++11 代碼(我有一些使用thread_local
和*this
引用) . 另一方面,如果它保留199711L
,它將使用安全的 C++98 代碼,這仍然可以。 這樣可能會錯過一些優化,但您仍然可以使用其他方法來檢測特定功能是否可用(編譯器版本、編譯器特定宏,如__GXX_EXPERIMENTAL_CXX0X__
、為您檢查編譯器宏的 boost 宏等)。 重要的是安全的默認值。
切換到 __cplusplus 的新值有 2 個可能的原因:
據我所知,所有切換的編譯器都屬於第二類。
我相信一些編譯器供應商對改變 __cplusplus 的值(最容易實現的 C++11 特性,良好的宣傳)過於熱情,而且有些更保守是好的。
截至 2018 年 4 月,MSVC 2017 現在可以正確報告宏,但前提是使用特定開關 ( /Zc:__cplusplus
)。 這是因為許多舊代碼依賴於檢測 MSVC 編譯器的宏的舊值。 資源
希望將來,一旦全世界的人們更新了他們的代碼,MS 將默認正確報告宏。
正如另一個答案中所指出的, /Zc:__cplusplus
幾乎就是答案。 假設您在文件夾層次結構下有一堆.vcxproj
文件,只需將名為Directory.Build.props
的文件放入公共父文件夾並按如下方式填充它:
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
</Project>
您也可以使用您自己的用戶屬性表在此處進行設置。 即在所有Microsoft.Cpp.*.user.props
文件中的%LOCALAPPDATA%\Local\Microsoft\MSBuild\v4.0
中(其中*
是目標平台的占位符)。
此外,在代碼中__cplusplus
像這樣_MSVC_LANG
或類似):
#if defined(__cplusplus) && defined(_MSVC_LANG) && (__cplusplus == 199711L)
// Check against _MSVC_LANG with the value you expect for __cplusplus
#else
// Check against __cplusplus as usual
#endif
我建議在您無法確定在命令行上指定/Zc:__cplusplus
時使用了您的代碼(例如,標題,因為您是庫作者)時使用類似的東西。
我仍然有點困惑,為什么在 VS2022 中仍然如此,因為如果您查看C++ 編譯器支持,Visual C++ 與所有其他的相比還不錯。
綜上所述,您可能希望使用功能測試宏而不是測試 C++ 標准版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.