17

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?

Catskul
  • 17,916
  • 15
  • 84
  • 113
  • 2
    "Why?" is presumably because some changes were invasive and couldn't be easily disabled. – Ben Voigt Jul 01 '14 at 15:24
  • 6
    Perhaps also because they don't break C++03 code and can therefore be considered extensions. – Joseph Mansfield Jul 01 '14 at 15:24
  • Any idea if there is documentation to support that? I thought c++11 was meant to be backward compatible. – Catskul Jul 01 '14 at 15:26
  • What happens with success.cpp if you use a vector of struct foo instead of int? – Nicolas Jul 01 '14 at 15:28
  • @Catskul _"I thought c++11 was meant to be backward compatible."_ No, it is not backwards compatible. http://stackoverflow.com/questions/6399615 – Drew Dormann Jul 01 '14 at 16:45
  • There is no way a lambda was valid C++03 code. I suspect the reason is a mix of who implemented it, how hard it was to cordon off, and when it was implemented: stuff back when C++11 was rare and unstable, vs mature and expected (today). – Yakk - Adam Nevraumont Jul 01 '14 at 17:14
  • 12
    This question appears to be off-topic because it is about design decisions made by the creators of clang, which can likely only be answered by them, and are very likely quite opinion based. – PlasmaHH Jul 01 '14 at 19:17
  • 1
    Is clang 3.4 still C++03 compliant without -std=c++11? Range-based for loop can be considered as an extenstion, what about the usage of the "auto" keyword ? – Nicolas Jul 02 '14 at 08:26
  • 1
    @PlasmaHH, I do not agree that this is off topic. While it's possible that it's simply a design decision, it's also very possible that there are conceptual and standards based answers. There is not another better stackexchange site for this question, and it is extremely relevant to C++ programmers deciding which features are "safe" to use. – Catskul Aug 25 '14 at 04:53
  • 1
    @Catskul: You are free to disagree with everything. It seems though that I am not alone in thinking that the way flags to a compiler work is not mandated by the standard and solely based on the ideas and opinions of whoever created that compiler. In the time since asking that question you could also have posted it to the relevant clang mailing list. There isn't an SE for every question... – PlasmaHH Aug 25 '14 at 16:33
  • @plasmaHH the question fits well within the guidelines related to on/off topic: http://stackoverflow.com/help/on-topic Please indicate which guideline you feel was broken. – Catskul Aug 25 '14 at 17:26
  • @Catskul: Please indicate which of the currently four bullet points you think this question fits into, I can't find any. – PlasmaHH Aug 25 '14 at 18:28
  • @PlasmaHH "software tools commonly used by programmers" – Catskul Aug 25 '14 at 18:29
  • @Catskul: that point means usage of them, not reasoning about design decisions of their authors. Anyways there is a better format for this: a question on meta.SO. If you want to clarify the community stance on this, thats a better thing to do. – PlasmaHH Aug 25 '14 at 18:54
  • @plasmaHH 1) You're already presupposing that the answer to the post is going to be "it's an arbitrary design decision" 2) that such a decision is not relevant to use. Knowing why some features are automatically available allows developers to know what it safe to use, and whether the reason is standards based may mean the difference between code being compilable on more than on compiler 3) the guidelines do not suggest that such questions are unwelcome. – Catskul Aug 25 '14 at 21:04
  • @plasmaHH FWICT the community stance is not unclear. IMO, your stance is unclear. However I've opened a MSE post to this effect. – Catskul Aug 25 '14 at 21:19
  • @Catskul Why do you think that C++ features that are available by default are any more or less safe than features that require the `--std=c++11` option? – nobody Aug 25 '14 at 22:00
  • @AndrewMedico for portability reasons. If all compilers expose the same c++11 features without explicit request, then they are "safe" If they don't it would be easy to accidentally write code that would compile for clang, but not gcc for example. – Catskul Aug 25 '14 at 23:15
  • @Catskul if you care about portability, you should **always** specify which language version you intend to use and never rely on what is being accepted by some compiler version "without explicit request". That's the whole purpose of having standards. You should also enable pedantic warnings or even errors to make sure that you are not accidentally using a language extension that might not work with a different compiler. – oxygene Aug 26 '14 at 07:34
  • 1
    @plasmaHH The original question was which features from the newest standard are enabled by default, without using the "-std= " flag to target that standard? To me this is clearly a question about usage. The 'why?' is ancillary. However if this behavior is addressing a technical limitation, or is intended as a feature I can use to my advantage; Knowing how the authors intended their tool to be used is important, regardless of what the standard says or if one agrees with them! Just my $0.02 – Garrick Sep 04 '14 at 19:51

1 Answers1

3

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.

Stefan Weiser
  • 2,264
  • 16
  • 25
  • Good answer, I shall have to try this! I went digging and saw that language extensions page but couldn't fit the puzzle pieces together. – Garrick Sep 04 '14 at 19:55