Boost's "cstdint" Usage - c++

Boost's C99 stdint implementation is awfully handy. One thing bugs me, though. They dump all of their typedefs into the boost namespace. This leaves me with three choices when using this facility:
Use "using namespace boost"
Use "using boost::[u]<type><width>_t"
Explicitly refer to the target type with the boost:: prefix; e.g., boost::uint32_t foo = 0;
Option № 1 kind of defeats the point of namespaces. Even if used within local scope (e.g., within a function), things like function arguments still have to be prefixed like option № 3.
Option № 2 is better, but there are a bunch of these types, so it can get noisy.
Option № 3 adds an extreme level of noise; the boost:: prefix is often ≥ to the length of the type in question.
My question is: What would be the most elegant way to bring all of these types into the global namespace? Should I just write a wrapper around boost/cstdint.hpp that utilizes option № 2 and be done with it?
Also, wrapping the header like so didn't work on VC++ 10 (problems with standard library headers):
namespace Foo
{
#include <boost/cstdint.hpp>
namespace boost_alias = boost;
}
using namespace Foo::boost_alias;
EDIT: I guess another option is to use the preprocessor to make it work on VC 10? Taking the snippet above:
#ifndef FOO_HPP_INCLUDED
#define FOO_HPP_INCLUDED
#if _MSC_VER >= 1600 /*VC++ 10*/ || defined USE_NATIVE_STDINT_HEADER
#include <stdint.h>
#else
namespace cstdint_wrapper
{
#include <boost/cstdint.hpp>
namespace boost_alias = boost;
}
using namespace cstdint_wrapper::boost_alias;
#endif
#endif
Less work, I guess?

I just use C99's stdint.h (it's actually now in VS 2010). For the versions of Visual C/C++ that don't include it, I use a public domain version from MinGW that I modified to work with VC6 (from when I had to work in VC6):
http://snipplr.com/view/18199/stdinth/
There are a couple other options you might consider in this SO question: C99 stdint.h header and MS Visual Studio
If you'd like to continue using boost/cstdint.hpp, I'd say that the suggestion of implementing a wrapper header that brings the types into the global namespace would be the way to go.
Does boost/cstdint.hpp provide anything I should know about that isn't in stdint.h?

Your idea of writing a wrapper header that implements option 2 is definitely the better of those three options.
What I'd suggest, though, is a slight variant: Put those using declarations within another namespace, such as cstdint or something; then, you have the option if putting using cstdint; in your own code or explicitly specifying cstdint:: on the particular uses.

If you included directly the file you will be forced to prefix it with std::. So the question is, which option would you take in this case. What would you do with the other types introduced by Boost? Would you prefix them with boost:: or not?
The fist one is clearly a bad option.
You can implement option two using your my_cstdint.hpp file
#include <boost/cstdint.hpp>
using boost::uint32_t;
...
and include my_cstdint.hpp in your application. But in my opinion it is a bad idea to add new symbols on the root namespace, you can get more conflicts as the types can be already defined by for example the stdint.h C file.
Even if the third option use a lot of characters, namespaces are there for this purpose. boost::uint32_t will be defined to the correct type depending on your toolset, so just use it, as you would use std::uint32_t.

I personally always use option 3. If things are too long, then you can use typedefs to reduce the amount of code.

Related

How to define a feature that will be implemented in next version of the Standard library?

I need functionality that will be added in the next C++ version (C++17). I am using MS Visual Studio, which implements C++11. I expect that in a few years I'll upgrade my compilation tools, so this functionality will be available via the Standard library.
In the meantime, I need to implement it manually. How can I define it so it will be easy to migrate in the future?
Let's take std::clamp as an example.
I can implement it with a different name, e.g. my_clamp. When I am able to use C++17, I can start using std::clamp, and optionally do a global replace of my_clamp by std::clamp. This looks ugly but probably will generate no surprises.
I can implement it in my namespace my::std, and do using namespace my. This way, I can start using the name std::clamp today, and not change it later. However, is it dangerous/forbidden?
I can somehow detect C++ version, and if it's less than 17, stuff clamp into std namespace. This is UB, but will probably work.
Is there a method without disadvantages?
Is there an accepted/customary way of doing this?
What I usually do in these cases is:
1. try to use a recent C++ compiler and library that already includes the functions/facilities that I need.
2. failing that (i.e. I'm forced to stay with an older C++ standard version, let's say C++11, because of old toolchains), find a library that has what I need
3. better yet, if what I need is already included in a newer C++ standard or a "reference implementation" library already exists, I try to use the reference implementation or a close one, this will reduce future changes in your code.
4. get familiar with the boost library, as there may be a good chance that it already includes what you need, and it may well be the reference implementation for the future C++ standard stuff.
5. failing all the above, for whatever reason, write your own implementation, but try to keep its interface similar to the standard proposal.
For anything not coming from the std:: namespace, use namespace aliasing to further reduce future changes (when switching to newer toolchain and std:: ).
Note 1: C++17 IS the current C++ standard, the next should be C++20.
Note 2: MS VS2017 (and 2015 to some extent) already includes some or most of the stuff from C++17.
Edited to include an example of how to use namespace alias
This example is related to C++ filesystem stuff, it is not (yet) updated to use C++17 , but it's still limited to .
It mainly rely on preprocessor #defines (i.e. HAVE_CXX_EXPERIMENTAL_FILESYSTEM) to enable/disable the wanted portion.
I usually use CMake to detect compiler and library features and to define those macros in an automated fashion.
#if _MSC_VER >= 1900 // Microsoft Visual C++ 2015
#define HAVE_CXX_EXPERIMENTAL_FILESYSTEM
#endif
#if defined(HAVE_CXX_EXPERIMENTAL_FILESYSTEM)
// Have Filesystem TS
#include <experimental/filesystem>
namespace filesystem = std::experimental::filesystem;
using std::error_code;
#elif !defined(NO_BOOST)
// Fall-back to Boost.Filesystem library
#include <boost/version.hpp>
#if (BOOST_VERSION >= 103400)
#include <boost/filesystem.hpp>
#else
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/exception.hpp>
#endif // (BOOST_VERSION >= 103400)
namespace filesystem = boost::filesystem;
using boost::system::error_code;
// Hack to fix differences with C++17 Filesystem TS
#define copy_options copy_option
#define overwrite_existing overwrite_if_exists
#else
#warning Not implemented
// or #include custom stuff
#endif
What the above basically does is a fall-through:
1. use and alias the namespace if available
2. use boost.filesystem (if not explicitly excluded with NO_BOOST)
3. [optional] fallback to a custom implementation or other library if needed.
Disclaimer: this solution may not be perfect, but it's reasonably working for my needs.

Is it OK to put a standard, pure C header #include directive inside a namespace? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it a good idea to wrap an #include in a namespace block?
I've got a project with a class log in the global namespace (::log).
So, naturally, after #include <cmath>, the compiler gives an error message each time I try to instantiate an object of my log class, because <cmath> pollutes the global namespace with lots of three-letter methods, one of them being the logarithm function log().
So there are three possible solutions, each having their unique ugly side-effects.
Move the log class to it's own namespace and always access it with it's fully qualified name. I really want to avoid this because the logger should be as convenient as possible to use.
Write a mathwrapper.cpp file which is the only file in the project that includes <cmath>, and makes all the required <cmath> functions available through wrappers in a namespace math. I don't want to use this approach because I have to write a wrapper for every single required math function, and it would add additional call penalty (cancelled out partially by the -flto compiler flag)
The solution I'm currently considering:
Replace
#include <cmath>
by
namespace math {
#include "math.h"
}
and then calculating the logarithm function via math::log().
I have tried it out and it does, indeed, compile, link and run as expected. It does, however, have multiple downsides:
It's (obviously) impossible to use <cmath>, because the <cmath> code accesses the functions by their fully qualified names, and it's deprecated to use in C++.
I've got a really, really bad feeling about it, like I'm gonna get attacked and eaten alive by raptors.
So my question is:
Is there any recommendation/convention/etc that forbid putting include directives in namespaces?
Could anything go wrong with
diferent C standard library implementations (I use glibc),
different compilers (I use g++ 4.7, -std=c++11),
linking?
Have you ever tried doing this?
Are there any alternate ways to banish the math functions from the global namespace?
I've found several similar questions on stackoverflow, but most were about including other C++ headers, which obviously is a bad idea, and those that weren't made contradictory statements about linking behaviour for C libraries. Also, would it be beneficial to additionally put the #include <math.h> inside extern "C" {}?
edit
So I decided to do what probably everyone else is doing, and put all of my code in a project namespace, and to access the logger with it's fully qualified name when including <cmath>.
No, the solution that you are considering is not allowed. In practice what it means is that you are changing the meaning of the header file. You are changing all of its declarations to declare differently named functions.
These altered declarations won't match the actual names of the standard library functions so, at link time, none of the standard library functions will resolve calls to the functions declared by the altered declarations unless they happen to have been declared extern "C" which is allowed - but not recommended - for names which come from the C standard library.
ISO/IEC 14882:2011 17.6.2.2/3 [using.headers] applies to the C standard library headers as they are part of the C++ standard library:
A translation unit shall include a header only outside of any external declaration or definition[*], and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header.
[*] which would include a namespace definition.
Why not putting a log class in it's own namespace and using typedef namespace::log logger; to avoid name clashes in a more convenient way?
Change your class's name. Not that big of a deal. ;-)
Seriously though, it's not a great idea to put names in the global namespace that collide with names from any standard header. C++03 didn't explicitly permit <cmath> to define ::log. But implementations were chronically non-conforming about that due to the practicalities of defining <cmath> on top of an existing <math.h> (and perhaps also an existing static-link library for some headers, including math). So C++11 ratifies existing practice, and allows <cmath> to dump everything into the global namespace. C++11 also reserves all those names for use with extern "C" linkage, and all function signatures for use with C++ linkage, even if you don't include the header. But more on that later.
Because in C++ any standard header is allowed to define the names from any other standard header (i.e, they're allowed to include each other), this means that any standard header at all can define ::log. So don't use it.
The answer to your question about different implementations is that even if your scheme works to begin with (which isn't guaranteed), in some other implementation there might be a header that you use (or want to use in future in the same TU as your log class), that includes <cmath>, and that you didn't give the namespace math treatment to. Off the top of my head, <random> seems to me a candidate. It provides a whole bunch of continuous random number distributions that plausibly could be implemented inline with math functions.
I suggest Log, but then I like capitalized class names. Partly because they're always distinct from standard types and functions.
Another possibility is to define your class as before and use struct log in place of log. This doesn't clash with the function, for reasons that only become clear if you spend way too much time with the C and C++ standards (you only use log as a class name, not as a function and not as a name with "C" linkage, so you don't infringe on the reserved name. Despite all appearances to the contrary, class names in C++ still inhabit a parallel universe from other names, rather like struct tags do in C).
Unfortunately struct log isn't a simple-type-identifier, so for example you can't create a temporary with struct log(VERY_VERBOSE, TO_FILE). To define a simple-type-identifier:
typedef struct log Log;
Log(VERY_VERBOSE, TO_FILE); // unused temporary object
An example of what I say in a comment below, based on a stated example usage. I think this is valid, but I'm not certain:
#include <iostream>
#include <cmath>
using std::log; // to enforce roughly what the compiler does anyway
enum Foo {
foo, bar
};
std::ostream &log(Foo f) { return std::cout; }
int main() {
log(foo) << log(10) << "\n";
}
It is ugly hack too, but I believe will not cause any linker problems. Just redefine log name from <math.h>
#define log math_log
#include <math.h>
#undef log
It could cause problems with inline functions from math using this log, but maybe you'd be lucky...
Math log() is still accessible but it's not easy. Within functions where you want to use it, just repeat its real declaration:
int somefunc() {
double log(double); // not sure if correct
return log(1.1);
}

Declaring namespace as macro - C++

In standard library, I found that namespace std is declared as a macro.
#define _STD_BEGIN namespace std {
#define _STD_END }
Is this a best practice when using namespaces?
The macro is declared in Microsoft Visual Studio 9.0\VC\include\yvals.h. But I couldn't find the STL files including this. If it is not included, how it can be used?
Any thoughts..?
Probably not a best practice as it can be difficult to read compared to a vanilla namespace declaration. That said, remember rules don't always apply universally, and I'm sure there is some scenario where a macro might clean things up considerably.
"But I couldn't find the STL files including this. If it is not included, how it can be used?".
All files that use this macro include yvals.h somehow. For example <vector> includes <memory>, which includes <iterator>, which includes <xutility>, which includes <climits>, which includes <yvals.h>. The chain may be deep, but it does include it it some point.
And I want to clarify, this only applies to this particular implementation of the standard library; this is in no way standardized.
In general No. The macros were probably used at the time when namespaces were not implemented by some compilers, or for compatibity with specific platforms.
No idea. The file would probably be included by some other file that was included into the STL file.
One approach that I saw in a library that I recently used was:
BEGIN_NAMESPACE_XXX()
where XXX is the number of namespace levels for example:
BEGIN_NAMESPACE_3(ns1, ns1, ns3)
would take three arguments and expand to
namespace ns1 {
namespace ns2 {
namespace ns2 {
and a matching END_NAMESPACE_3 would expand to
}
}
}
(I have added the newlines and indentation for clarity's sake only)
I imagine the only reason to do this is if you want to make it easy to change the namespace used by your application / library, or disable namespaces altogether for compatibility reasons.
I could see doing this for the C libraries that are included in C++ by reference (eg., the header that C calls string.h and that C++ calls cstring). In that case, the macro definition would depend on an #ifdef _c_plus_plus.
I wouldn't do it in general. I can't think of any compiler worth using that doesn't support namespaces, exceptions, templates or other "modern" C++ features (modern is in quotes because these features were added in the mid to late '90s). In fact, by my definition, compilers are only worth using if they offer good support for their respective language. This isn't a language issue; it's a simple case of "if I chose language X, I'd prefer to use it as it exists today, not as it existed a decade or two ago." I've never understood why some projects spend time trying to support pre-ANSI C compilers, for instance.

no std namespace

We've got a reasonable sized C++ application that's pretty old at this stage, so it's got a few quirks.
One of these quirks is in how it deals with C++ compilers that use a pre-standisation standard library. There's one header file that's supposed to resolve any differences between a standards compliant compiler and this one non-compliant compiler. For various reasons we can't / don't want to stop supporting this compiler.
#include <vector>
#include <set>
#if defined(NO_STD_LIB)
#include <iostream.h>
#else
#incude <iostream>
using std::string;
using std::cout;
using std::vector;
using std::cout;
#endif
You use this as follows
#include stl.h
int main() {
vector<string> foo;
.....
return 0;
}
There are 2 main issues with this approach:
Each compilation unit that includes std.h has to compile lots of un-needed code (and we're trying to reduce compile times as much as possible at the minute)
The global namespace gets polluted with pretty much everything that would normally be in the std namespace.
I really would like to address both of these points as part of a code cleanup project. The first one really is the more important reason for doing this.
As we have to support this old compiler then our code will always have to avoid clashing names with things that it exposes in it's standard lib, so point 2 isn't really relevant, though I'd like to see a solution that works when / if we can finally drop support for it.
My idea so far is to break up the super header into a set of smaller headers. e.g. stl_vector, stl_iostream, stl_set, etc. This way we can only include the parts of the standard library that we're interested in. These filenames follow the pattern of the std headers, but with an easily searched for prefix. So when the time comes to dump the offending compiler, it'll be simple to search for the prefix and remove it.
I think that will fix issue 1 easily enough.
My real problem is fixing issue 2. I thought of doing someting like this
#if defined(NO_STD_LIB)
#include <iostream.h>
#define std
#else
#include <iostream>
then we could code as follows:
#incude "stl_iostream"
int main() {
std::string foo("bar");
std::cout << foo << std::endl;
}
And that almost worked. Where there was no standard namespace the #define std made std::string decompose into ::string and life was good.
Then I tried this with a .cc file that used the dreaded "using namespace std;" and I get a compile error because that becomes "using namespace ", so that obviously won't work.
Now obviously I could ban people from writing "using namespace std;", but as much as it should be avoided in headers, it's sometimes useful in .cc files where you're making heavy use of lots of STL classes.
So, finally, to the question. Is there a standard idiom for dealing with this issue. Or if there isn't a standard way to deal with this, then what tricks do you use to support compilers that use a pre-standard standard library.
I've thought of using pre-compiled headers to solve the compilation speed issue, but we target different compilers and the effort of getting this working across all of them may mean its not worth our time doing it.
Answers that advise me to drop the non-conforming compiler may be popular, but won't be accepted as this is something that we can't do just now.
You can try:
#if defined(NO_STD_LIB)
namespace std {
using ::string;
using ::cout;
using ::vector;
using ::cout;
}
#endif
Then std::string will work.
It would have been much better if the using namespace ::; directive existed in the language; however it doesn't.

How can I wrap BOOST in a separate namespace?

I'm looking to have two versions of BOOST compiled into a project at the same time. Ideally they should be usable along these lines:
boost_1_36_0::boost::shared_ptr<SomeClass> someClass = new SomeClass();
boost_1_35_0::boost::regex expression("[0-9]", boost_1_35_0::boost::regex_constants::basic);
I read (well scanned) through the development list discussion. There's no easy solution. To sum up:
Wrapping header files in a namespace declaration
namespace boost_1_36_0 {
#include <boost_1_36_0/boost/regex.hpp>
}
namespace boost_1_35_0 {
#include <boost_1_35_0/boost/shared_ptr.hpp>
}
Requires modifying source files
Doesn't allow for both versions to be included in the same translation unit, due to the fact that macros do not respect namespaces.
Defining boost before including headers
#define boost boost_1_36_0
#include <boost_1_36_0/boost/regex.hpp>
#undef boost
#define boost boost_1_35_0
#include <boost_1_35_0/boost/shared_ptr.hpp>
#undef boost
Source files can simply be compiled with -Dboost=boost_1_36_0
Still doesn't address macro conflicts in a single translation unit.
Some internal header file inclusions may be messed up, since this sort of thing does happen.
#if defined(SOME_CONDITION)
# define HEADER <boost/some/header.hpp>
#else
# define HEADER <boost/some/other/header.hpp>
#endif
But it may be easy enough to work around those cases.
Modifying the entire boost library to replace namespace boost {..} with namespace boost_1_36_0 {...} and then providing a namespace alias. Replace all BOOST_XYZ macros and their uses with BOOST_1_36_0_XYZ macros.
This would likely work if you were willing to put into the effort.
Using bcp can install boost library to a specific location and can replace all 'namespace boost' in their code to a custom alias. Assuming our alias is 'boost_1_36_0' all 'namespace boost' code blocks will start with 'boost_1_36_0'. Something like
bcp --namespace=boost_1_36_0 --namespace-alias shared_ptr regex /path/to/install
, but check the documentation in the link yourself because I'm not sure if it is legal syntaxis.
#Josh:
While I agree with the shivering, I still believe this is the better course of action. Otherwise, linking troubles are a certainty. I've had the situation before where I had to hack the compiled libraries using objcopy to avoid definition conflicts. It was a nightmare for platform interoperability reasons because the name mangling works very differently even in different versions of the same compilers (in my case, GCC).
You'll have a world of trouble linking because the mangled names will be different. And yes, I see you knew that, but it seems like it will be trouble all around.

Categories