0

I'm starting to add [[nodiscard]], [[noreturn]] and [[fallthrough]] to my code base, but I still worry the code might need to be used on an older C++ version.

I'm only worried about g++, clang, and Visual Studio.

To be safe should I make every single usage depend on a version check for the exact version it appeared? Or, do these compilers accept (or does the spec even mandate they accept) any [[attribute]] even if unknown, starting with C++11?

Were these allowed and ignored (or supported) even before C++11? (I ask not what the spec says but what the software actually did.)

#if __cplusplus >= 201703L
#define MyNamespace_NoReturnCPP17 [[noreturn]]
#else
#define MyNamespace_NoReturnCPP17
#endif

(Off subject but if I were on the C++ committee, I'd re-use the case keyword to do the same thing as switch, when followed by (, except it would in effect have an automatic break before each case label. And within the case's block (and nowhere else), fallthrough would be accepted as a keyword, that suppresses that automatic break.)

I note the C++14 spec 7.6.1.5 says behavior is "implemenation-defined" but I'm asking a more practical question about what compilers actually did. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

The C++17 spec 10.6.1.6 says "Any attribute-token that is not recognized by the implementation is ignored." That answers my question for C++17 and newer, but again my question is about earlier compilers. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

Swiss Frank
  • 1,985
  • 15
  • 33
  • 3
    Which compilers are you targeting? Because checking [`__cplusplus` is not always a good choice](https://stackoverflow.com/q/57102212/332733). So what you're trying to do is a lot more complicated than it seems. If your minimum is C++17 then just call it that and work around where and when you need to and don't waste time and effort otherwise. – Mgetz Nov 01 '22 at 14:13
  • *"but I still worry the code might need to be used on an older C++ version"* - Because there's an actual potential consumer of your code using an "older" version? How much "older" are we talking about? C++17 is itself 5 years old now, a good while in IT terms. – StoryTeller - Unslander Monica Nov 01 '22 at 14:32
  • 1
    There is literally no limit on how quirky older compilers can be. But I do know that compilers often claim `__cplusplus` without a perfect feature match. I know boost has extensive compiler version detection based macros, I'd consider looking at what it does. – Yakk - Adam Nevraumont Nov 01 '22 at 19:12

1 Answers1

1

To be safe should I make every single usage depend on a version check for the exact version it appeared? Or, do these compilers accept (or does the spec even mandate they accept) any [[attribute]] even if unknown, starting with C++11?

I prefer adding version checks for safety although mainstream compilers will throw a warning for unknown attributes.

I'm not sure these warning options(and corresponding behavior) have been added since the first C++11 feature-complete version, so you'd better do some checks.

Were these allowed and ignored (or supported) even before C++11?

Since standard attributes syntax is supported starting from C++11, compilers will have trouble at the parsing stage. Demo

Nimrod
  • 2,908
  • 9
  • 20