Getting a LNK2005 "already defined in GUI.obj" for a function pointer in PAL.h
//GUI.cpp
#include "PAL.h"
//PAL.h
#define PAL_INCLUDE
int (*addPAL)( int, void(*)(), void(*)() );
//main.cpp
#include "GUI.h"
#ifndef PAL_INCLUDE
#include "PAL.h"
#endif
Have I misunderstood the nature of includes and #ifndef?
You're getting the error probably because the preprocessor is processing main.cpp before GUI.cpp.
Try changing the content of your PAL.h to this:
#ifndef PAL_INCLUDED
#define PAL_INCLUDED
// definitions
#endif
Reference
Include guard
I think you should use the include guard over PAL.h.
If I understand what you're trying to do, this code is much more clear (and quite common out there):
GUI.h
#ifndef _GUI_H_
#define _GUI_H_
...
#endif
GUI.cpp
#include "PAL.h"
...
PAL.h
#ifndef _PAL_H_
#define _PAL_H_
int (*addPAL)( int, void(*)(), void(*)() );
#endif
main.cpp
#include "GUI.h"
#include "PAL.h"
...
Hope it helps.
Main.cpp and GUI.cpp are compiled separately from each other and then linked together. This means the preprocessor state is reset between the two compiles, and you lose the definition of PAL_INCLUDE
Header guards stop a header from being included more than once by other headers in the same compile unit, not to prevent clashes in the linker.
Try putting static in front of the method declaration - it limits the function to the current unit, thus preventing this problem.
For more information, see What is a “static” function?
addPal is getting defined twice, once in GUI.cpp and once in main.cpp. What you want is to define it once and declare it everywhere you need to use it. I suggest putting
int (*addPAL)( int, void(*)(), void(*)() );
in one of the .cpp files (I haven't seen enough code to decide which one it belongs in), then the declaration:
extern int (*addPAL)( int, void(*)(), void(*)() );
in the header file. The extern tells the compiler that the pointer addPAL exists, but is defined elsewhere
Related
Suppose I have two data structures that reference each other. I want to put them into their separate header files like this:
// datastruct1.h
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
#include <datastruct2.h>
typedef struct DataStructOne_t
{
DataStructTwo* two;
} DataStructOne;
#endif
and
// datastruct2.h
#ifndef DATA_STRUCT_TWO
#define DATA_STRUCT_TWO
#include <datastruct1.h>
typedef struct DataStructTwo_t
{
DataStructOne* one;
} DataStructTwo;
#endif
and I have a main function:
#include <datastruct1.h>
#include <datastruct2.h>
int main()
{
DataStructOne* one;
DataStructTwo* two;
}
However my compiler complains:
$ gcc -I. -c main.c
In file included from ./datastruct1.h:4,
from main.c:1:
./datastruct2.h:8:2: error: unknown type name ‘DataStructOne’
8 | DataStructOne* one;
| ^~~~~~~~~~~~~
Why is that? What can I do to fix this?
Why?
In order to understand why, we need to think like a compiler. Let's do that while analysing main.c line by line. What would a compiler do?
#include <datastruct1.h>: Put "main.c" aside (push to the stack of files being processed) and switch to "datastruct1.h"
#ifndef DATA_STRUCT_ONE: hmm, this is not defined, let's continue.
#define DATA_STRUCT_ONE: OK, defined!
#include <datastruct2.h>: Put "datastruct1.h" aside and switch to "datastruct2.h"
#ifndef DATA_STRUCT_TWO: hmm, this is not defined, let's continue.
#define DATA_STRUCT_TWO: OK, defined!
#include <datastruct1.h>: Put "datastruct2.h" aside and switch to "datastruct1.h"
#ifndef DATA_STRUCT_ONE: this is now defined, so go straigh to #endif.
(end of "datastruct1.h"): close "datastruct1.h" and pop current file from the stack of filles. What were I doing? Ahh, "datastruct2.h". Let's continue from the place where we left.
typedef struct DataStructTwo_t ok, starting a struct definition
DataStructOne* one; Wait, what is DataStructOne? We have not seen it? (looking up the list of processed lines) Nope, no DataStructOne in sight. Panic!
What happened? In order to compile "datastruct2.h", the compiler needs "datastruct1.h", but the #include guards in it "datastruct1.h" prevent its content from being actually included where it's needed.
The situation is symmetrical, so if we switch the order of #include directives in "main.c", we get the same result with the roles of the two files reversed. We cannot remove the guards either, because that would cause an infinite chain of file inclusions.
It appears that we need "datastruct2.h" to appear before "datastruct1.h" and we need "datastruct1.h" to appear before "datastruct2.h". This does not seem possible.
What?
The situation where file A #includes file B which in turn #includes file A is clearly unacceptable. We need to break the vicious cycle.
Fortunately C and C++ have forward declarations. We can use this language feature to rewrite our header files:
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
// No, do not #include <datastruct2.h>
struct DataStructTwo_t; // this is forward declaration
typedef struct DataStructOne_t
{
struct DataStructTwo_t* two;
} DataStructOne;
#endif
In this case we can rewrite "datastruct2.h" the same way, eliminating its dependency on "datastruct1.h", breaking the cycle in two places (strictly speaking, this is not needed, but less dependencies is always good). Alas. this is not always the case. Often there is only one way to introduce a forward declaration and break the cycle. For ecample, if, instead of
DataStructOne* one;
we had
DataStructOne one; // no pointer
then a forward declaration would not work in this place.
What if I cannot use a forward declaration anywhare?
Then you have a design problem. For example, if instead of both DataStructOne* one; and DataStructTwo* two; you had DataStructOne one; and DataStructTwo two;, then this data structure is not realisable in C or C++. You need to change one of the fields to be a pointer (in C++: a smart pointer), or eliminate it altogether.
One way to resolve the circular dependency and still use the typedefs where possible is to split the headers into two parts with a separate guard macro for each part. The first part provides typedefs for incomplete struct types and the second part completes the declarations of the struct types.
For example :-
datastruct1.h
#ifndef DATA_STRUCT_ONE_PRIV
#define DATA_STRUCT_ONE_PRIV
/* First part of datastruct1.h. */
typedef struct DataStructOne_t DataStructOne;
#endif
#ifndef DATA_STRUCT_ONE
#define DATA_STRUCT_ONE
/* Second part of datastruct1.h */
#include <datastruct2.h>
struct DataStructOne_t
{
DataStructTwo *two;
};
#endif
datastruct2.h
#ifndef DATA_STRUCT_TWO_PRIV
#define DATA_STRUCT_TWO_PRIV
/* First part of datastruct2.h. */
typedef struct DataStructTwo_t DataStructTwo;
#endif
#ifndef DATA_STRUCT_TWO
#define DATA_STRUCT_TWO
/* Second part of datastruct2.h */
#include <datastruct1.h>
struct DataStructTwo_t
{
DataStructOne *one;
};
#endif
main.c
/*
* You can reverse the order of these #includes or omit one of them
* if you want.
*/
#include <datastruct1.h>
#include <datastruct2.h>
int main(void)
{
DataStructOne *one;
DataStructTwo *two;
}
As mentioned in the comment in main.c above, only one of the headers needs to be included since the other header will be included indirectly anyway.
Well, if both structures reference each other, it is clear that they must be related. The best thing you can do is to put both in one include file (as they are related) but putting them in different and making the compiler to read from one include the other will make the compiler to read the main file... .from main file start reading include A until it gets to the point to include B, and start reading B to the point of the include A again(we'll start reading A again in a recursive manner that has no end) you will never stop reading each file and worse, you will get an error the second time you see the same struct definition (because it has been already defined before)
To allow the user to include any or both files without a problem, a define is made when include file A is encountered:
File A.h
#ifndef INCLUDE_FILE_A
#define INCLUDE_FILE_A
/* ... the whole stuff of file A with the proper includes of other files.*/
#include "B.h"
#endif /* INCLUDE_FILE_A */
and in
File B.h
#ifndef INCLUDE_FILE_B
#define INCLUDE_FILE_B
/* ... the whole stuff of file B with the proper includes of other files.*/
#include "A.h"
#endif /* INCLUDE_FILE_B */
so the definitions made in file A are only used if INCLUDE_FILE_A has not been included previously, and skip them if file A has been included already (and the same for B.h, of course).
If you make the same on file B (but instead with INCLUDE_FILE_B) then you will be secure that both files will be included in either order (depending on how you did it in the first case) and will never be included again (making th e inclussion secure of returning back to the main file.
I recently came across something that goes against my understanding of includes.
I am creating a dll to hold basic coordinate objects for a personal game engine I'm developing (for fun).
Main dll header file.
#pragma once
#include "sclapi.h"
#include "vector.h"
#include "point.h"
// Other includes and stuff.
// Unimportant for this demonstration.
sclapi.h
#pragma once
#ifdef SCL_EXPORTS
#define SCL_API __declspec(dllexport)
#else
#define SCL_API __declspec(dllimport)
#endif
vector.h
#pragma once
// No includes
/*EDIT*/struct Point;
struct SCL_API Vector {
float x, y;
// Other stuff
explicit operator Point() const;
};
point.h
#pragma once
// No includes
struct SCL_API Point {
int x, y;
// Other stuff
explicit operator Vector() const;
};
My code works perfectly fine; but to my understanding, it shouldn't. A header file should only know what's declared in it (includes being shorthand for pasting in code). None of these objects are declared in the other's header files. [EDITED] point.h should have no knowledge of a Vector struct. Whats more, both even have knowledge of the SCL_API macro. If I comment out individual includes in the main header file, I get the expected compiler errors. What am I missing?
EDIT:
After further testing, I discovered that a declaration of the later objects needs to be in the first header file 'vector.h'; but after, they do not need to be declared again in any other header file. Also, declaring the classes in the main header file does not work. The Point forward declaration must be inside the vector.h file.
When you #include a file, it gets automatically "copypasted" into your source.
Because you included vector.h right before including point.h, the Point class will see it.
However, it's not a good idea to rely on this behavior as the order of includes might change and thus it will not work anymore, so you should #include "vector.h" in your point.h.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does this not prevent multiple function declarations?
Global.h
#ifndef Global_h
#define Global_h
#include <iostream>
unsigned char exitStatus;
#endif
OutputHandler.h
#ifndef OutputHandler_h
#define OutputHandler_h
#include "Global.h"
class OutputHandler {
private:
static bool instanceExists;
// more code
#endif
Root.h
#ifndef Root_h
#define Root_h
// declarations
OutputHandler *output;
#endif
Root.cpp
#include "Root.h"
// gets instance of OutputHandler
// more code
I am getting errors regarding exitStatus, static bool instanceExists, and static class output being already defined by Root.obj in OutputHandler.obj. I assume the issue is with including the header file OutputHandler.h in both Root.h and OutputHandler.cpp. Anyone know how to fix this or how to better organize header files?
Because include guards only work at the translation unit level (you can, for this simple case, consider a single C file to be a translation unit).
That means a single C file, if it includes the header file twice, will not process it the second time due to the include guards.
However, if you include the header from two different C files, each of them will get a copy of the variables defined in that header.
Then, when you link them together, you get the duplicates.
The easiest way to get around this problem is to never define things in headers, only declare them.
So, in the header (eg, xyzzy.h), you have:
extern int xyzzy; // declare but don't define.
and in all the C files that want to use that, put:
$include "xyzzy.h"
and, in one of those C files, also put:
int xyzzy; // define it here, once.
You can think of declaration as a simple "I declare that this exists somewhere, just not here", while definition is "I an creating this here and now".
Declare extern usigned char exitStatus in Global.h and define it in one implementation file.
The problem is during the linking phase; include guards in the headers won't help you.
In C, there is the separate concepts of declarations and definitions. Declarations are what are put into headers; they merely state that a particular variable exists. The definition of a variable is where storage is actually allocated for it.
For example, in your Global.h, you have:
#ifndef Global_h
#define Global_h
#include <iostream>
usigned char exitStatus;
#endif
This is defining a variable called exitStatus, and the linker is complaining because any given variable should only be defined in one place in a program. What you need to do is declare it in the header, and then define it in only one place in a source (*.cpp) file. For example, your header should declare exitStatus with:
extern char exitStatus;
and in only one source file, define it with:
char exitStatus;
The situation is similar for output in Root.h, as well as any other place you should be declaring variables in the header file.
See also: http://www.cprogramming.com/declare_vs_define.html
Api.cpp:
int (*theFunc) (int);
theFunc = (int (*) (int)) DlSym(hSo, "theFunc");
So far so good.
Now, I want to make a header so that other cpp files can also call theFunc.
Api.h: per How to declare function pointer in header and c-file?
extern int (*theFunc)(int);
/usr/bin/ld: Warning: type of symbol `theFunc' changed from 2 to 1 in Api.o
OK, so this is a warning that theFunc is seen as a function from one compilation element and as a variable in another. (Reference) This seems like bad things will happen at runtime.
This seems to be a proper declaration, what am I doing wrong?
Edit: Actually running in linux, so use DlSym not Microsoft GetProcAddress() call
According to the linked post, condense it to one line, not two in the .cpp file. So the .h seems right, and put this in the .cpp file:
int (*theFunc) (int) = (int (*) (int)) GetProcAddress(hDll, "theFunc");
You're not doing declaration and assignment in one shot like the linked answer is. With what I posted above, you will be.
You probably should not include Api.h
Alternatively you may work with macros in a way that api.h behave somewhat different when included by api.cpp.
MicroSoft has done/do such things.
api.h
#ifdef _API_
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int (*theFunc)(int);
api.cpp
#define _API_
#include "api.h"
...
other.cpp
#define _OTHER_
#include "api.h"
...
I need to create structure like this:
// file main.h:
#pragma once
#ifndef _MAIN_H
#define _MAIN_H
#include <iostream>
#include "first.h"
#include "second.h"
#endif
// -----------------
// file first.h:
#pragma once
#ifndef _FIRST_H
#define _FIRST_H
#include "main.h" // because of using SomeFunction() in first.cpp
int SomeVar; // used in first.cpp
#endif
// -----------------
// file second.h:
#pragma once
#ifndef _SECOND_H
#define _SECOND_H
#include "main.h" // because of using SomeVar in second.cpp
int SomeFunction(); // implemented in second.cpp
#endif
// -----------------
By logic, if main.h will be compiled first, then each of this headers will be included only once and all variables/functions will be defined normally.
For example, this configuration compiled normally in IAR C++ Compiler, if set up in options "preinclude file" (not precompiled) to main.h.
But, in Visual Studio 2010 same structure causes linker errors like:
1>second.obj : error LNK2005: "int SomeVar" (?SomeVar##3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction##3HA) already defined in first.obj
I think because of including files in alphabetic order. Apparently pragma- and define-guards are ignored by linker.
Errors can be fixed by additional header and external variables definitions, but this is hard and wrong way.
Question is: What should i do?
int SomeVar; // used in first.cpp
Variables should never be defined in headers. They should be declared with extern:
extern int SomeVar; // used in first.cpp
Then you can actually define them in "first.cpp" with int SomeVar;.
Also, "first.h" does not need to include "main.h". Headers should only include files if the definitions in that header absolutely need the contents of those files. The definitions in "first.h" do not need anything in "main.h". Therefore, it should not include it.
If "first.cpp" needs to include something from "second.h", then it is the responsibility of "first.cpp" to include it.
In the header file use extern keyword as:
//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere
Then in .cpp file define it and use it:
//first.cpp
int SomeVar; //definition is here
As for SomeFunction, have you defined it header file itself? Re-check it. :-)