Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a known set of `c++11` features in clang enabled by default not requiring `-std=c++11`?

Tags:

c++

c++11

clang

It appears that clang (3.4) automatically accepts some c++11 (e.g. auto, for(:)) without a special flag (though producing a warning), but not other parts (e.g. lambdas).

For example the following compiles clang++ c++11.success.cpp:

#include <vector>
int main( int argCount, char ** argVec )
{
    std::vector<int> vec;

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

    return 0;
}

but this fails 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;
}

With clang++ c++11.failure.cpp -std=c++11 of course it succeeds.

I couldn't find any specific documentation as to which c++11 features are supported without -std=c++11 and why. Anyone have a clue?

like image 618
Catskul Avatar asked Jul 01 '14 15:07

Catskul


1 Answers

Clang has (as any other C++ compiler) some language extensions (there is a list of C++11 extensions, that are available in C++03). One of this extensions is the range based for loop. You can test it by #if __has_extension(cxx_range_for) .... It will generate a warning anyway (if you do not disable it with -Wno-c++11-extensions). You could test the features with:

#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;
}

Curiously this warns, that the type inference extension and feature is off, but it validly compiles the auto pointer (I guess, that this is because of the old meaning of auto as storage class specifier):

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
 ^

To get fully standard compliant, you should treat warnings as errors by enabling -Werror.

like image 137
Stefan Weiser Avatar answered Nov 11 '22 06:11

Stefan Weiser