I'm using Xcode to build a C++ project.
But I don't understand the error message:
"Apple Mach-O linker command failed with exit code 1"
I found that #include is the reason.
I have two .cpp file which include a same .h file. If I remove #include of one, it will be build successfully.
Other header files are fine expect the header file described above. I already used "ifndef".
#ifndef include guards only work at the level of the translation unit (usually a single source file).
If you define the same object twice in two translation units, that won't be fixed by include guards but the linker will complain bitterly when you try to combine the two object files into a single executable.
I suspect your situation is akin to:
hdr.h:
#ifndef HDR_H
#define HDR_H
void rc(void);
int xyzzy;
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
void rc(void) { xyzzy = 0; }
In a situation like that, the include guard will prevent the header being included twice in prog1.c but it will still be included in both prog1.c and prog2.c, meaning that each will have a copy of xyzzy.
When you link them together, the linker will not like that.
The solution is to not define things in headers but to merely declare them there, leaving the definition for a C file:
hdr.h:
#ifndef HDR_H
#define HDR_H
int rc(void);
extern int xyzzy; // declare, not define
#endif
prog1.c:
#include "hdr.h"
#include "hdr.h"
int main (void) { rc(); return xyzzy; }
prog2.c:
#include "hdr.h"
int xyzzy; // define
int rc(void) { xyzzy = 0; }
Declarations are things like function prototypes, extern variables, typedefs and so on (simplistically, things that declare something exists without actually creating an "object").
Definition are things that create "objects", like non-extern variables and so on.
You need to track down what "object" is being defined twice (the linker output should have something like doubly-defined symbol 'xyzzy') and then make sure it's not defined in the header.
Related
I want to run a small simulation in c++.
To keep everything nice and readable I seperate each thing (like all the sdl stuff, all the main sim stuff, ...) into it's own .h file.
I have some variables that I want all files to know, but when I #include them in more then one file other the g++ compliler sees it as a redefinition.
I understand why he does this, but this still leaves me with my wish to have one file where all important variables and constants for each run are defined and known to all other files, to easily find and change them when running my simulation.
So my Question here: Is there a good workaround to achieve that or something similar?
You can put the declarations for all the globals in a header and then define them in a source file and then you will be able to use those global variables in any other source file by just including the header as shown below:
header.h
#ifndef MYHEADER_H
#define MYHEADER_H
//declaration for all the global variables
extern int i;
extern double p;
#endif
source.cpp
#include "header.h"
//definitions for all the globals declared inside header.h
int i = 0;
double p = 34;
main.cpp
#include <iostream>
#include "header.h" //include the header to use globals
int main()
{
std::cout << i <<std::endl;//prints 0
std::cout<< p << std::endl;//prints 34
return 0;
}
Working demo
Mark them as extern in the header and have one translation unit that defines them.
Note: Without LTO (link time optimization) this will seriously slow down your simulation.
1) I know a non-const variable is external linkage by default (it's like it's been declared as external more or less) but i don't understand why can't i define a global variable such as int glbl_a in header
//test.h
#ifndef TEST_H
#define TEST_H
int glbl_a=0; //wrong -> "multiple definition of `glbl_a`"
static int st_glbl_a=1; //ok to initialize it in header!
extern int ext_glbl_a; //ok to declare it and define it in test.cpp
#endif
//test.cpp
#include "test.h"
using namespace std;
//st_glbl_a=22; i could use st_glbl_a but it wouldn't affect st_glbl_a in main cause of 'static'
int ext_glbl_a=2; //definition of external gloabal non-const variable
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
extern int glbl_a; //declaration of glbl_a external
int main(){
cout<<glbl_a;
}
the working version for this program is the one in which I define int glbl_a=0; in test.cpp only and declare extern int glbl_a; in main before using it in output (definition in test.h is just commented, that is there's nothing about glbl_a).
2)the working version doesn't work anymore if I group all definitions/declaretions into a namespace spread onto test.cpp and test.h (MyNamespace) cause of int glbl_a in test.cpp:
//test.h
#ifndef TEST_H
#define TEST_H
namespace MyNamespace{
//extern int glbl_a;
}
#endif
//test.cpp
#include "test.h"
using namespace std;
namespace MyNamespace{
int glbl_a=0;
}
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
int main(){
cout<<MyNamespace::glbl_a; //wrong -> "'glbl_a' is not a member of 'MyNaspace'"
}
it would work only if I de-comment declaration in test.h, but why?
Problem 1
Including a header effectively pastes the included file into the including file, producing one large file that is then compiled (and, typically, promptly deleted). This means that every including file now has its very own glbl_a. The compiler is happy, but when the linker attempts to put everything together, it finds many equally valid pretenders to the name glbl_a. The linker hates this and doesn't even try to figure out what you're trying to do. It simply spits out an error message and asks that you fix the problem.
Problem 2
test.cpp and main.cpp are different translation units. They compile to produce different, completely independent objects. Neither can see what's in the other, so the fact that MyNamespace::glbl_a exists in test.cpp is lost on main.cpp. When main.cpp is compiled, the compiler builds a list of identifiers declared in the file constructed from main.cpp and all of its included headers. MyNamespace::glbl_ais never declared as of when it is first used (or after for that matter) so the compiler spits out an error message.
Uncommenting the declaration in test.h means the compiler will find MyNamespace::glbl_a in main.cpp and will allow it's use. Since MyNamespace::glbl_a is defined in test.cpp the linker can find one-and-only-one MyNamespace::glbl_a and can successfully link.
extern does not allocate storage. Instead it is a promise to the compiler that the variable being declared will be fully defined and allocated somewhere else, maybe later in the file or in another file. The variable exists, somewhere, and compilation can continue. The linker will call you out as a liar if it cannot find a definition.
More details here: How does the compilation/linking process work?
More on extern: When to use extern in C++ and Storage class specifiers
headers will be included by other files (more than one) thus if you define in header, it will be in each translation unit thus lead to "multiple definition"
I'm trying to add some utility functions and global variables to my code in such a way that I can be able to use them in every class I want in my project. I would like to use a .hpp file for the definitions end a .cpp file for the implementation.
This is a summary of these two files:
// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp
namespace utils {
int global_variable1;
int global_variable2;
void utility_function1(...);
void utility_function2(...);
void utility_function3(...);
}
#endif /* utilities_hpp */
and the implementation:
// This is Utilities.cpp
#include "Utilities.hpp"
namespace utils {
void utility_function1(...) {
// Some code
}
void utility_function2(...) {
// Some code
}
void utility_function3(...) {
// Some code
}
}
Other than my main.cpp file I have two other classes. My main.cpp file includes Class1.hpp header that includes Class2.hpp header.
Now I thought that I could put another #include "Utilities.hpp" in Class1.hpp or Class2.hpp without any problems since I've used the guards in that header. The thing is that when I try to do that the linker throws me this error: Apple Mach-O Linker (ld) Error Group - clang: error: linker command failed with exit code 1 (use -v to see invocation) and I can't understand why or what to do to solve it.
I'm using Xcode 8.3 on a macOS Sierra 10.12.4.
I hope I was able to explain my problem, thank you all very much in advance.
You've violated the One Definition Rule. global_variable1 and global_variable2 should be declared extern in your header and defined in exactly one translation unit (probably Utilities.cpp).
You've defined global variables in a header that gets included in multiple translation units, so there's a utils::global_variable1 defined in main.cpp, and one in Utilities.cpp. When it comes to link time, the linker has no way to know which global_variable1 to use, so it throws an error.
To fix it, add the extern keyword to your declarations and add a definition in "Utilities.cpp":
Utilities.hpp:
// This is Utilities.hpp
#ifndef utilities_hpp
#define utilities_hpp
namespace utils {
extern int global_variable1;
//^^^^^^ <-----HERE
extern int global_variable2;
//^^^^^^ <-----HERE
void utility_function1(...);
void utility_function2(...);
void utility_function3(...);
}
#endif /* utilities_hpp */
Utilities.cpp:
// This is Utilities.cpp
#include "Utilities.hpp"
namespace utils {
int global_variable1; //<---- Definitions added
int global_variable2;
void utility_function1(...) {
// Some code
}
void utility_function2(...) {
// Some code
}
void utility_function3(...) {
// Some code
}
}
You're missing the extern keyword on your global variables in your header. As a result, you're defining them, which results in multiple definitions when you include the header in two different source modules.
Once you add the extern in the header file (extern int global_variable1;), you'll need to add the definition in your .cpp file where you also define your functions.
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.
hey everyone, i got code like this:
//a.h
#ifndef SB
#define SB
namespace A{ int a = 10; int b = 10;}
#endif
however, if I imported the a.h in a.cpp file, the compiler would complain:
error LNK2005: "int A::a" (?a#A##3HA) already defined in a.obj
It looks like compiler would combine .h file and .cpp file together without explicit "import" statement. But it doesn't make sense to me that it would happen with the macro guard defined.
I use Visual C++
#include guards prevent one file from including the same .h file multiple times. They don't prevent multiple files from each including the same .h file once, which is what I assume is happening to you. Move your definitions into a single .cpp file and leave just a declaration here:
namespace A {
extern int a;
extern int b;
}
which tells the compiler that these variables exist somewhere, but their definitions can be found elsewhere.
Chances are you have a cyclic #include statement some where that is putting the header file into both object files and then trying to link the object files together gets the duplicate entries.
Remember that when you #include what the compiler is doing is cut/pasting the contents of the .h file in place of the line the include is on.
You will want to declare prototypes in the .h file, not the actual declaration of those objects and their values.
If you want a and b to have constant values, you can do this:
//a.h
#ifndef SB
#define SB
namespace A{const int a = 10; const int b = 10;}
#endif
and it will not be a problem to include it in several places.
If you need the values to change, you should follow dfan's advice.