I've a single header requirement on a code, which means there should be no splitting of declarations and definitions into separate header and source files. I've implemented it properly and it works as intended for my use case, where this header file was meant to be included in only single source file.
Now when it comes to it's use in multiple source files(where more than one .cpp includes it), it will fail with linker error along the lines that some variables are being redeclared. That is because I've the code like -
#ifndef HEADER_HPP
#define HEADER_HPP
....
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
void doSomething(){
[uses if(R_coutbuf) and others]
}
....
#endif HEADER_HPP
Now the best solution would be to declare those vars in header file and define/assign them in single cpp file, but as I said I want to be able to do this with a single header file. Which brings to the problem that if multiple source files will include it, there will be redeclarations.
So far I'm not sure how should I be able to do this but I've two ideas -
#ifdef DEFINE_VARIABLES
#define EXTERN /* nothing */
#else
#define EXTERN extern int
#endif /* DEFINE_VARIABLES */
EXTERN global_variable = something;
I'm not so sure about it, would this even work?
And the second way I thought about is to put it in an anonymous namespace, am trying this one and so far its building successfully -
#ifndef HEADER_HPP
#define HEADER_HPP
....
namespace R {
namespace {
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
}
void doSomething(){
[uses if(R_coutbuf) and others]
}
}
....
#endif HEADER_HPP
Is there any other way I could achieve this? Are there any problems with either of the ways I described above.
Answer: The include guards in header file in C, C++ is used to avoid compiler error i.e. redefinition of function, variable or class.
Re “How do you fix a redefinition error in C programming?”, you do that by removing the redefinition. Compilers can get confused when subjected to unexpected repetition in source code. So when they complain about it, the fix is to find and remove the repetition.
A redefinition is an attempt to redefine the same variable, e.g.: int a = 5; int a = 6; Also. int foo(); is not a definition. It's a declaration.
In C, you cannot redefine an existing variable.
You could make your variable a local static variable in a function:
inline std::streambuf const*& R_coutbuf() {
static std::streambuf const* b = std::cout.rdbuf();
return b;
}
Are there any problems with either of the ways I described above.
Macro trick
Internal linkage (anonymous namespace)
const
and all will have the same value at run time, the linker may be able to throw away the duplicates. In any case, the difference is only a few bytes worth for your program. Modifying individual variables as opposed to modifying a shared variable would change the meaning of the program.For comparison, let us consider separate source file option, which you have ruled out.
Is there any other way I could achieve this?
Not really. You can use static
keyword instead of anonymous namespace to declare internal linkage.
PS. If you define any non-template functions in the header, they must be declared inline. Your anonymous namespace example fails to do this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With