I have the following header:
#ifndef MY_H_
#define MY_H_
namespace A {
void f() {
// do something
}
}
#endif
However, when I compiled, I got errors like multiple definition of A::f(). I thought that the #ifndef check is enough to avoid duplicate definitions in 1 translation unit. Maybe I miss something?
Thanks in advance.
Add inline specifier before the function definition:
#ifndef MY_H_
#define MY_H_
namespace A {
inline void f() {
// do something
}
}
#endif
You should declare functions in the header file but define them in your cpp file. If you include this header file from multiple translation units (which is most probable), then there will be multiple implementations available for different translation units. Each of your cpp files that includes this header will have an implementation of f. This way, if f is to be called, it is ambiguous. By putting the implementation into a cpp file, it can be linked and used that way. But there is only one implementation available which makes it unambiguous.
So, your header file should be:
#ifndef MY_H_
#define MY_H_
namespace A
{
void f(); // declaration only
}
#endif
and your source file:
#include "myHeader.h"
namespace A
{
void f()
{
// some implementation
}
}
Then, you should be fine. You would usually do that with all of your functions. The only exceptions are inline functions/methods or templates but this is beyond the scope of this question.
Related
I have created header file abc.hpp which contains a namespace of multiple functions.
When I use single source file which includes the header and call the function defined in namespace it works well, but when I call the same function in project where I have to include this header in multiple places, compilation gives me multiple definition error.
My other files are created as library and get executed.
abc.hpp:
#ifndef __ABC_HPP__
#define __ABC_HPP__
namespace abc {
void sendtext(const char* msg)
{
create_context(mycontext);
send_context(create_context,msg)
}
void sendtextwitherrno(const char* msg, int errn)
{
create_context(mycontext);
send_context(create_context,msg, errn)
}
};
#endif
test.cpp:
#include"abc.hpp"
int main()
{
abc::sendtext("hello world");
abc::sendtextwitherrno("hello error no",140);
return 0;
}
You can treat header files as if they are copy-pasted into your implementation files. So by putting function definitions into your headers, those definitions appear in multiple translation units (roughly, compiler .cpp files). This is not allowed - how is the compiler supposed to tell between them if they end up different?
Usually you would have a .h/.cpp pair, with function declarations going in the .h, and function definitions going in the .cpp. This way the definition only appears once in your whole program.
I can split your code like this:
abc.hpp:
#ifndef __ABC_HPP__
#define __ABC_HPP__
// function **declarations**
namespace abc{
void sendtext(const char* msg);
void sendtextwitherrno(const char* msg, int errn);
}
#endif
abc.cpp:
#include "abc.hpp"
#include "context.hpp" // I guess this might be where create_context and send_context come from
// function **definitions**
namespace abc{
void sendtext(const char* msg){
create_context(mycontext); // not sure where mycontext is supposed to live?
send_context(create_context,msg)
}
void sendtextwitherrno(const char* msg, int errn){
create_context(mycontext);
send_context(create_context,msg, errn);
}
}
test.cpp:
#include "abc.hpp"
int main(){
abc::sendtext("hello world");
abc::sendtextwitherrno("hello error no",140);
return 0;
}
Another way is to mark the functions as inline - this tells the compiler you are deliberately repeating the function definition all over the place, and you'd better be sure the definition is always identical. How sure are you? Are there different macros or different compiler flags in place in different places the function is used?
I have an interface ver as
// ver.h
class ver
{
public:
virtual void func()=0;
};
Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);
#endif
and
// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_b
);
#endif
Now the implementations
//ver1.h
#include "test\header.h"
class ver1:public ver
{
public:
FuncPoint f;
};
and
//ver2.h
#include "test2\header.h"
class ver2:public ver
{
public:
FuncPoint f;
};
and ver1.cpp and ver2.cpp will be using the respective f
Now the polymorphic behavior comes into play here
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return new ver1();
else
return new ver2();
}
Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile.
On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.
I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.
A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.
Is there some other better way to fix this?
EDIT:
I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).
Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):
//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a);
class ver1 : public ver
{
public:
FuncPoint_a f;
static ver1 *create();
};
Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.
Following your code it would become:
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return ver1::create();
else
return ver2::create();
}
In this way the two colliding headers will never be included in the same file.
I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.
I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.
I'd like to use a certain namespace along with its functions to be used in several forms to have sort of shared functions. However, I am having linker problem.
Here is what I did - I created a new unit and inside of it I wrote in header file:
#ifndef MyHeaderH
#define MyHeaderH
namespace MyHeader
{
enum { SOMETHING1, SOMETHING2 };
void SomeFunction(int Param);
}
#endif
Of course, the actual function is defined in cpp file, the above is just from h file.
And the cpp file is as follows:
#pragma hdrstop
#include "MyHeader.h"
#pragma package(smart_init)
void SomeFunction(int Param)
{
//some code here
}
So in my main form Form1 I include the above in hpp file of Form1
MyHeader::SomeFunction(0);
This all compiles fine but the linker reports unresolved external. So obviously it doesn't see the namespace and function. How do I fix that?
As an additional question - if I use such function set in several forms, it should be all compiled just once and reused right (it won't have several copies of same functions I guess?)
You probably forgot to put the function definition in the namespace.
It's either done like you do in the header file, but with a function body:
namespace MyHeader
{
void SomeFunction(int Param)
{
// ...
}
}
Or using the scope operator :::
void MyHeader::SomeFunction(int Param)
{
// ...
}
The actual function is defined in the cpp file in a way that it does not implement the interface declared in the header file.
Implement
namespace MyHeader
{
void SomeFunction(int Param) { /* Your implementation goes here. */ }
}
in the cpp file.
I've read a lot for this problem ,but I haven't found a proper solution.
So i have 4 files:
includes.h - which contains all libraries I need in other files + some global functions
cities.h - which contains declarations of 2 classes
cities.cpp - which contains definitions of the 2 classes in cities.h
source.cpp - where is the main functon
And I have(and need) these includes
//cities.h
#include "includes.h"
//cities.cpp
#include "cities.h"
//source.cpp
#include "cities.h"
I've tried almost all combinations of #ifndef in all of the files and the program continues to give me the same error: function_X already declared in cities.obj.And this error repeats for all functions in "includes.h".
Please help me.This makes me a lot of headaches.
As you've described in the comments, you have function definitions in your includes.h header file. When this is included in multiple implementation files, you end up with multiple definitions of those functions in your program. This breaks the one definition rule. You should simply declare functions in includes.h and move their definitions into a includes.cpp file.
Something like this:
// includes.h
void foo();
int bar(int);
// includes.cpp
void foo() {
// implementation
}
int bar(int x) {
// implementation
}
I'm going to try and preempt a question that typically follows this answer. No, your include guards (#ifndef ...) are not meant to prevent this. They only prevent a header being included multiple times in a single translation unit. You are including the header in multiple translation units, which an include guard does not stop.
On top of what #sftrabbit said, If you are making a headers only library where you need to define the functions in the the header file this is possible with the keyword inline.
// includes.h
inline void foo() {
// implementation
}
inline int bar(int x) {
// implementation
}
This use of inline is not to be mistaken with its other use as a compiler suggestion to inline the function call.