Mutliple header & source files in cpp, pretty sure a duplicate thread [duplicate] - c++

I have a header file "USpecs.h":
#ifndef USPECS_H
#define USPECS_H
#include "Specs.h"
#include <iostream>
#include <vector>
std::vector<Specs*> UcakSpecs;
#endif
I am using this header both in main function and another class named Ucak.
But when i build it the following error occurs:
Ucak.cpp|6|multiple definition of `UcakSpecs'|
As i searched before, it should be okay with #ifndef but it is not.

The include guards only prevent multiple definitions within a single translation unit (i.e. a single source file with its included headers). They do not prevent multiple definitions when you include the header from multiple source files.
Instead, you should have a declaration in the header:
extern std::vector<Specs*> UcakSpecs;
and a definition in one (and only one) source file:
std::vector<Specs*> UcakSpecs;

Inclusion guards only prevent the header from being included in the same translation unit more than once. If you include this header in multiple translation units, you will have multiple definitions of UcakSpecs across the program.
The way to declare a global variable is to declare it as extern in the header file:
#ifndef USPECS_H
#define USPECS_H
#inclde "Specs.h"
#include <iostream>
#include <vector>
extern std::vector<Specs*> UcakSpecs;
#endif
A global variable declared as extern is only a declaration.
Then make sure it is only defined in a single translation unit by defining it in an implementation file (perhaps in USpecs.cpp);
std::vector<Specs*> UcakSpecs;

The #ifndef only applies to a single compilation unit. Since you have two (the main function and Ucak class), the variable is defined twice.
Consider declaring the variable as extern in the header file:
extern std::vector<Specs*> UcakSpecs;
and defining it inside the Ucak.cpp file:
std::vector<Specs*> UcakSpecs;
This should work.

Related

method already defined (template class)

I am getting the error "method already defined in class.obj" on ALL my methods,
I've seen that some of the solutions include separating the class into a header and a .cpp file but it's not possible in this case.
Any help will be much appreciated.
this is my h file: http://pastebin.com/k46JEQBH
the cpp has:
#include "stdafx.h"
#include "poly.h"
The problem is your definitions are in your header, and it's probably being included in multiple .cpp files. Each .cpp file is a new translation unit. Imagine you compile each .cpp file one at a time. For each .cpp file that includes your header, it will be the first time that header is encountered, POLY_H will not have been defined yet. Declarations are allowed to appear multiple times, but definitions are not. Move your definitions to a separate .cpp file and everything should work.
Edit: Keeping the definition in your header is necessary and allowed for template classes, but your class is not templated.
Could it be your usage of #pragma once? What compiler are you using?
And have you tried using include guards instead to see if that resolves the errors? For example:
#ifndef POLY_H
#define POLY_H
//your code minus the pragma once
#endif //POLY_H

What is the scope of pre-compiler define in c++?

Is the scope of the pre-compiler define the file where it defined?
for example:
three files :
test1.hpp/test1.cpp
test2.hpp/test2.cpp
test3.hpp/test3.cpp
An within test1.cpp:
#ifndef test1_hpp
#define test1_hpp
// some declarations
#endif
test2.hpp and test.hpp both #include test1.hpp. If the scope of test1_hpp is the whole application, as far as I understand, there can only one include test1.hpp success. Because once included, test1_hpp is defined.
test2.hpp and test.hpp both #include test1.hpp. If the scope of test1_hpp is the whole application, as far as I understand, there can only one include test1.hpp success. Because once included, test1_hpp is defined.
The compiler works on translation units (think: individual .cpp files) not the whole application (think: executable). What you call "the scope of the pre-compiler define" is the current translation unit. In your example, the // some declarations part in test1.hpp would be visible/processed in each of the CPPs that include test1.hpp directly or indirectly i.e. in all of test1.cpp (directly), test2.cpp, test3.cpp (indirectly, via both #include test1.hpp).
The #ifndef test1_hpp is a common idiom to prevent inadvertent inclusion of the same header file multiple times within the same translation unit - see for example "Use of #include guards" on Wikipedia.
Your assumption is correct. If you use the #ifndef guard in your header, the first time that test1.hpp is included in your application by the pre-processor, test1_hpp will be defined and will allow the inclusion of the code in your header. In future includes of test1.hpp, the code won't be re-included thanks to the guard.
This is needed, in most part, to prevent double definitions upon including the header in multiple files of your project, and comply with the one definition rule.

c++ header file redefenition error

*note: I am new to c++, so sorry if I make an obvious mistake.
I am getting an error on all of my variables. I am trying to use headers and forward declarations. Here is a snippet of my code:
//BotRenderer.h
#ifndef BOTRENDERER_H_
#define BOTRENDERER_H_
#include <SDL2/SDL.h>
SDL_Texture *botTextures[217];
int currentBotFrame;
//BotRenderer.cpp
#include "BotRenderer.h"
SDL_Texture *botTextures[217];
int currentBotFrame = 0;
All of the lines with variables give the error, '[variable name here] previously declared here'. What can I do to fix this?
The problem is that include guards only protect against multiple inclusion in the same translation unit (source file).
If you define a variable in a header file and include it in more than one source file then the variable will be defined in both source files (translation units), and when you then link the generated object files together the linker will notice that the variable is defined in both object files and give you an error.
What you should do is declare the variables in the header file, the easiest to do it is to add the extern keyword before the declaration, like
extern SDL_Texture *botTextures[217];
extern int currentBotFrame;
Regarding your compiler error, you get it just because you define the variables in both the header file and in the source file. The solution you your problem is the same, declare in header file and define in source file.
You should read about the One Definition Rule (a.k.a. ODR).

C++ mass-#include

I always need to write #include "headername.h" when including another class. Is it possible to acess other classes without writing it or including more than 1 class with a "#include"?
What the #include directive does is exactly what its name implies, it literally includes the contents of the wanted file into the source. It's done at an early step in the compilation process, before the actual compiler gets the source. The source with all its headers files is called translation unit, and it's on this translation unit that the compiler works on.
As for why you need the header files, remember that C++ needs everything to be declared or defined before it's being used. If the compiler doesn't know there is a class named Foo you can't declare variables of type Foo. If you don't #include the header file there Foo is defined, the compiler simply will not know there is such a class.
If you end up having to include many headers in many source files, you can put the common headers in another header file, whose only purpose is to include other header file. For example, if you in many source file includes <string>, <vector> and <iostream>, then you create a file called headers.h containing
#ifndef HEADERS_H__
#define HEADERS_H__
#include <iostream>
#include <string>
#include <vector>
#endif // HEADERS_H__
Then you can include this file in your source files instead:
#include "headers.h"
You can create your own header file which includes the necessary includes and then include this header file.

C++ include guards do not seem to be working

I am getting error messages from the mbed C++ compiler that seem to be indicative of malfunctioning include guards.
In main.cpp, I include my header file as follows:
#include "mbed.h"
#include "sample.h"
This is my sample.h:
#include "mbed.h"
#ifndef STUFF_H
#define STUFF_H
/* LEDs */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
/* Subroutines */
void sweepLEDs();
void pulseLEDs(int numPulses);
void clearLEDs();
#endif
In sample.cpp, I am including sample.h as follows:
#include "sample.h"
In both main.cpp and sample.cpp, I am referring to variables led1, led2, led3, led4 without declaring them. However, the compiler is outputting these complaints:
" Symbol led1 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."
...
" Symbol led4 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."
Are my include guards written improperly? Or is there some other issue?
(For reference, here is the link to the mbed.h source)
The issue is a misunderstanding of what include guards do. Include guards prevent the compiler from seeing the same content again in the same translation unit (for the same .cpp file). They do not prevent separate translation units from seeing the same code.
In your header file, you define (not just declare) the variables. Therefore every translation unit which includes the header creates its own copy of those variables.
The correct way to do it is to define the variables in a .cpp file and only declare them in the header (the include guards should be there anyway, to prevent multiple inclusion in the same translation unit).
That is, in your file sample.h, prefix your variables with extern and remove the initializer (so they are only declared, not defined), and define them in the corresponding .cpp file (the one where also the functions are defined), by putting the exact definitions from your header there.
In an unrelated note, you should put the #include "mbed.h" in sample.h inside the include guards, because some compilers optimize compile speed for such guards, and that optimization doesn't work if there's material outside the include guards. Note that this is not really a correctness issue (assuming mbed.h is properly protected by include guards as well), but a compiling performance issue.
You need to mark the declarations as "extern" like this:
extern DigitalOut led1;
Then define them (i.e. allocate storage for them) in sample.cpp by using the expression you used to have in the header.