默认情况下,clang 中是不是有一组已知的 `c++11` 功能不需要`-std=c++11`?

Posted

技术标签:

【中文标题】默认情况下,clang 中是不是有一组已知的 `c++11` 功能不需要`-std=c++11`?【英文标题】:Is there a known set of `c++11` features in clang enabled by default not requiring `-std=c++11`?默认情况下,clang 中是否有一组已知的 `c++11` 功能不需要`-std=c++11`? 【发布时间】:2014-07-01 15:20:36 【问题描述】:

clang (3.4) 似乎会自动接受一些 c++11(例如 auto,for(:))而没有特殊标志(尽管会产生警告),但不接受其他部分(例如 lambdas).

例如以下编译clang++ c++11.success.cpp:

#include <vector>
int main( int argCount, char ** argVec )

    std::vector<int> vec;

    for( auto & item : vec )
    
        ++item;
        

    return 0;

但这失败了clang++ c++11.failure.cpp:

#include <vector>
int main( int argCount, char ** argVec )

    std::vector<int> vec;
    auto lambda = [] ( int & foo )  return ++foo; ; //This line fails at []

    for( auto & item : vec )
    
        lambda( item );
    

    return 0;

clang++ c++11.failure.cpp -std=c++11 当然成功了。

我找不到任何关于在没有-std=c++11 的情况下支持哪些c++11 功能以及原因的具体文档。有人知道吗?

【问题讨论】:

“为什么?”大概是因为某些更改是侵入性的,不能轻易禁用。 也许也因为它们不会破坏 C++03 代码,因此可以被视为扩展。 这个问题似乎是题外话,因为它是关于 clang 的创建者做出的设计决策,这很可能只能由他们来回答,并且很可能是基于意见的。 在没有 -std=c++11 的情况下,clang 3.4 是否仍符合 C++03?基于范围的for循环可以认为是一种扩展,“auto”关键字的用法呢? @PlasmaHH,我不同意这是题外话。虽然这可能只是一个设计决策,但也很有可能存在基于概念和标准的答案。对于这个问题,没有其他更好的 stackexchange 站点了,它与 C++ 程序员决定哪些功能“安全”使用非常相关。 【参考方案1】:

Clang (与任何其他 C++ 编译器一样)有一些 language extensions(有一个 C++11 扩展列表,在 C++03 中可用)。这种扩展之一是基于范围的 for 循环。您可以通过#if __has_extension(cxx_range_for) ... 进行测试。无论如何它都会产生一个警告(如果你不使用-Wno-c++11-extensions 禁用它)。您可以使用以下方法测试这些功能:

#if __has_extension(cxx_range_for)
#warning __has_extension(cxx_range_for) is true
#else
#warning __has_extension(cxx_range_for) is false
#endif

#if __has_feature(cxx_range_for)
#warning __has_feature(cxx_range_for) is true
#else
#warning __has_feature(cxx_range_for) is false
#endif

#if __has_extension(cxx_auto_type)
#warning __has_extension(cxx_auto_type) is true
#else
#warning __has_extension(cxx_auto_type) is false
#endif

#if __has_feature(cxx_auto_type)
#warning __has_feature(cxx_auto_type) is true
#else
#warning __has_feature(cxx_auto_type) is false
#endif

int main()

        return 0;

奇怪的是,这警告说,类型推断扩展和功能已关闭,但它有效地编译了自动指针(我猜,这是因为 auto 作为存储类说明符的旧含义):

main.cpp:2:2: warning: __has_extension(cxx_range_for) is true [-W#warnings]
#warning __has_extension(cxx_range_for) is true
 ^
main.cpp:10:2: warning: __has_feature(cxx_range_for) is false [-W#warnings]
#warning __has_feature(cxx_range_for) is false
 ^
main.cpp:16:2: warning: __has_extension(cxx_auto_type) is false [-W#warnings]
#warning __has_extension(cxx_auto_type) is false
 ^
main.cpp:22:2: warning: __has_feature(cxx_auto_type) is false [-W#warnings]
#warning __has_feature(cxx_auto_type) is false
 ^

要完全符合标准,您应该通过启用-Werror 将警告视为错误。

【讨论】:

好答案,我得试试这个!我去挖掘并看到了语言扩展页面,但无法将拼图拼凑在一起。

以上是关于默认情况下,clang 中是不是有一组已知的 `c++11` 功能不需要`-std=c++11`?的主要内容,如果未能解决你的问题,请参考以下文章

最近的一组3分

我的 Linux 开发项目的 Clang vs GCC

C 中是不是有一组用于动态字符串、列表和字典的标准库?

mac 系统路径下的clang,clang++,ld,c++ 与xcode下的是否同一个

如何设置来用clang/clang++替换Linux下的默认编译器Gcc

macosx Catalina是不是总是默认使用clang?