2

Currently we work on a library that is allowed to use C++11/14 features and types when possible but must fallback to a C++03 implementation otherwise. Users and developers of this library are encouraged to use types and templates from namespace std.

Problems arise when using types from namespace std introduced by newer versions of the C++ Standard which are not shipped with the compiler used. One suggested option is to provide 'backports' for certain types that do not rely on new language features into namespace std as part of our library code, e.g. Fixed width integer types:

//file: std_backport.h

namespace std_backport {
    typedef char  int8_t;  //for platforms where 'char' is 8 bit
    typedef short int16_t; //for platforms where 'short' is 16 bit
    //[and so on]
}

//enter 'sacred' territory and introduce the types to namespace std
namespace std {
    using namespace ::std_backport;
}

Another example would be the tuple type which is provided by VS2010 in the technical report:

//file std_tuple_backport.h
#include <tr1/tuple>                //std::tr1::tuple

namespace std {
    using ::std::tr1::tuple;
}

Of course we have to provide checks to enable/disable the inclusion of those files according to the compilers used.

I did some research on this matter and aware of the fact, that extending the namespace std like this is undefined behavior I wanted to drop this idea. But than I came across this answer which states in #4:

Putting anything in std namespace is an "undefined behaviour". That means the specification does not say what will happen. But if you know that on particular platform the standard library does not define something, just go ahead and define it. [...]

So my questions are:

  • Can please someone clarify to me what exactly is meant by 'undefined behavior' in this case?
  • Is providing C++11/14 compatibility like this considered 'bad practice' even if we just provide types from a newer standard?
  • What would be an alternative or even better way to achieve this kind of code compatibility without having to define everything from namespace std in an own namespace and use this instead of namespace std?
Community
  • 1
  • 1
PiJ
  • 151
  • 1
  • 12
  • You could introduce a new namespace `mystd` with all your fancy new features and also `using namespace std;` in it, and everywhere in code where you want to use namespace `std`, just use `mystd`. – alexeykuzmin0 Dec 16 '16 at 13:15
  • *undefined behavior* means the behavior of the program is undefined. It may work just fine, it might generate a compiler error, it might have a subtle bug that way only hit .01% of the time. What it means is we lose the ability to reason what the code would do on any standard conforming compiler. – NathanOliver Dec 16 '16 at 13:17
  • 1
    I think you should use the Boost library. Much of this is already solved there. And if you want to stick to doing it yourself, do it like Boost does, which is like what you have in your third point: Yes, do that. – Rene Dec 16 '16 at 13:19
  • Hmpf, didn't find this one, before asking the question: http://stackoverflow.com/questions/34629249/inject-namespace-experimental-to-std Mea culpa if this might be considered a duplicate... – PiJ Dec 16 '16 at 15:19

1 Answers1

1

Can please someone clarify to me what exactly is meant by 'undefined behavior' in this case?

Same as in every other case. The standard doesn't guarantee any behaviour.

The program might fail to compile, succesfully compile but crash, not crash and have expected output, or unexpected output depending on any variable such as the compiler, the CPU architechture or the phase of the moon. As far as the standard is concerned.

Is providing C++11/14 compatibility like this considered 'bad practice' even if we just provide types from a newer standard?

If I care about standard compliance of the program - and I often do, then I consider it a bad practice.

What would be an alternative or even better way to achieve this kind of code compatibility without having to define everything from namespace std in an own namespace and use this instead of namespace std?

You don't need to define everything from std. Simply define the missing features in another namesace (or use a third party implementation), and use the existing features from the std namespace.

eerorika
  • 232,697
  • 12
  • 197
  • 326