Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>.

like image 559
mic_e Avatar asked Sep 07 '12 19:09

mic_e


People also ask

Should I use header files in C?

Header files are needed to declare functions and variables that are available. You might not have access to the definitions (=the . c files) at all; C supports binary-only distribution of code in libraries.

What should be included in C header?

The header file contains only declarations, and is included by the . c file for the module. Put only structure type declarations, function prototypes, and global variable extern declarations, in the . h file; put the function definitions and global variable definitions and initializations in the .

Does order of header files matter in C?

Ideally, all header files should be self-contained, and inclusion order should not matter. In practice, people often write header files that are not self-contained, and sometimes inclusion order does matter.

What is the purpose of C header files?

The header file eliminates the labor of finding and changing all the copies as well as the risk that a failure to find one copy will result in inconsistencies within a program. In C, the usual convention is to give header files names that end with .


1 Answers

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.

like image 131
CB Bailey Avatar answered Oct 16 '22 07:10

CB Bailey