Passing declaration of struct between .cpp files without using global header file - c++

Suppose I have main.cpp and functions.cpp, a struct type named myStruct was declared in main.cpp.
Now, I need to process an array of myStruct in main.cpp using a function in functions.cpp.
Sample Code:
// main.cpp
#include "functions.cpp"
struct myStruct {
int x;
}
myStruct structArray[5];
int main()
{
...(some code)...
process(structArray);
}
// functions.cpp
void process(struct myStruct array[])
{
...(some code)...
}
After doing some searching, I found the most common solution is to use a global header file, in which declare myStruct, and then include the header file in both main.cpp and functions.cpp.
Unfortunately, I am required to use only two files to complete such a program, which means I couldn't add a separate header.h, making me confused.
Can anyone give me some suggestions on an alternative of a global header in this situation? Thanks.

I think you can do that using only two .cpp files
My idea is to have declaration of struct myStruct in both main.cpp and fucntion.cpp and to have process function declaration in main.cpp. like this..
// main.cpp
struct myStruct {
int x;
};
void process(struct myStruct array[]);
myStruct structArray[5];
int main()
{
...(some code)...
process(structArray);
}
and
// functions.cpp
struct myStruct {
int x;
};
void process(struct myStruct array[])
{
...(some code)...
}
And compile each separately and link together at linking time.

#include is like copying and pasting contents of the file. So if you define a struct in functions.cpp and include this file in main.cpp, you can access internals of this struct there.
Note however, that by convention you SHOULD NOT include .cpp (or other sources) files. In this case I would rather rename functions.cpp to functions.h and declare function there, if you really need to do it using only two files.
If you really really really can not move defintion of the struct from main.cpp to functions.* for whatever reason you could also include functions.* in main.cpp after the defintion of the struct, but this is a very ugly solution. If you work with strange requirements it would be a solution tough I would do everything else to avoid that.

Related

How to access a structure array from 2 different files?

How would I go about doing something like this?
header.h
struct myStruct;
extern myStruct array[];
main.cpp
#include "header.h"
struct myStruct{
int a = 0;
};
myStruct array[5];
array[0].a = 1;
file2.cpp
#include "header.h"
std::cout << array[0].a;
The size and layout of myStruct needs to be known everythere you try to access its contents, so you must either define it inside of the .h file, or only access it using opaque pointers and dedicated functions.
Also, using C arrays in C++ is somewhat outdated. You should use STL containers instead, such as std::array<T, N> or std::vector<T>.
Well, first of all you should put struct declarations in the header files.
Second, you can't put assignments to arrays or std::cout statements just loose in files. I'm assuming you did this for short code and not because you didn't know it needed to be in a function, but I'm pointing it out just in case.
Third, struct declarations require a semicolon
What you would do is have a header file:
header.hpp:
#pragma once
struct MyStruct {
int a = 0;
};
extern MyStruct array[5];
The extern here means that the data is somewhere else. So let's make the somewhere else.
header.cpp:
#include "header.hpp"
MyStruct array[5];
main.cpp:
#include "header.hpp"
void someFunction() {
...
array[0].a = 1;
...
}
file2.cpp:
#include <iostream>
#include "header.hpp"
void someOtherFunction() {
...
std::cout << array[0].a;
...
}
How would I go about doing something like this?
You could go about doing something like what you did by doing something like what you did, except fixing the bugs in your attempt. Here is the list of bugs:
You failed to end the definition of myStruct with a semicolon.
.c suffix is conventionally for C source files while you're writing C++. Your compiler will likely be confused unless you provide some unconventional options to the compiler.
You use cout which you forgot to declare. Or did you intend to use std::cout? In that case you must include <iostream> in order to use it, and use the appropriate namespace.
In file2.c, you use the class myStruct in a way that depends on the definition of myStruct without providing that definition.
array[0].a = 1; and cout << array[0].a; are expression statements. Expression statements may not be in namespace scope, and must be within a block scope. In your program, those expression statements are in the namespace scope which makes the program ill-formed.

Static variable redefinition with Visual C++

I have 2 files each containing a static int variable which has the same name :
test-1.cpp:
#include "test-2.cpp"
static int a;
int main() {
}
test-2.cpp:
static int a;
void fonction() {
}
When I compile with cl test-1.cpp on command line, I get this error:
test-1.cpp(3): error C2086: 'int a' : redefinition
Because you include test2.cpp into test-1.cpp the actual code seen by the compiler is this:
static int a;
void fonction() {
}
static int a;
int main() {
}
Hence the redefinition.
The #include preprocessor command includes the file textually.
What you actually want is have both files test-1.cpp and test-2.cpp included into the Visual Studio project.
You want this:
test-1.cpp
#include "test-2.h"
static int a;
int main() {
fonction();
}
test-2.cpp
#include "test-2.h"
static int a;
void fonction() {
}
test-2.h
void fonction();
Of course, you are #including test-2.cpp in test-1.cpp. It's as if you have only one file. If you remove the #include and do this command
cl test-1.cpp test-2.cpp
then it will work.
This whole area is called separate compilation and it's something that newbies struggle with (it's also not often taught very well). Because of separate compilation you should never include one cpp file in another cpp file. Instead you should hand both files to the compiler so they can be compiled separately.
If one cpp file needs to know what's defined in another cpp file, then create a header file with declarations of what's in the second cpp file and include that in the first cpp file.
In this line;
#include "test-2.cpp"
you tell the preprocessor to put the content of test-2.cpp into test-1.cpp. Hence you define static int a; twice. This is not allowed. To fix this, remove the #include.
Note that you need to carefully distinguish between declarations (which can occur many times) and definitions (which can occur only once). Have a look at this thread for more info.

Multiple declaration vs not defined

I'm trying to import variables from a file that are used in a class in other file and ultimately import that to yet another file and compile.
Let me show what the reproduction of the problem looks like:
arrayFile.hpp
int arr[] = {
1,2,6,5,4,3
};
classFile.hpp
#include <iostream>
using namespace std;
#include "arrayFile.hpp"
class MyClass{
private:
int v1;
public:
MyClass();
void setV(int v);
int getV();
int funcM();
};
classFile.cpp
#include <iostream>
using namespace std;
#include "classFile.hpp"
MyClass::MyClass(){};
void MyClass::setV(int v){
v1 = v;
}
int MyClass::getV(){
return v1;
}
int MyClass::funcM(){
return v1*arr[0];
}
mainfile.cpp
#include <iostream>
using namespace std;
#include "classFolder/classFile.hpp"
// #include "classFolder/arrayFile.hpp"
// should i include this?
int main(){
MyClass c;
c.setV(3);
cout<<c.funcM()<<endl;
cout<<arr[0]<<'*'<<c.getV()<<endl;
}
The objective is to acess the array from both the classFile.cpp and mainfile.cpp, but I'm not managing to do this.
If I don't include arrayFile.cpp in mainfile.cpp:
/tmp/cce4ZHbp.o:(.data+0x0): multiple definition of `arr'
/tmp/ccmsYdmt.o:(.data+0x0): first defined here
If I do:
In file included from mainfile.cpp:5:0:
classFolder/arrayFile.hpp:1:9: error: redefinition of ‘int arr []’
int arr[] = {
^
In file included from classFolder/classFile.hpp:3:0,
from mainfile.cpp:4:
classFolder/arrayFile.hpp:1:5: note: ‘int arr [6]’ previously defined here
int arr[] = {
^
I've was able to get the compiler to tell me arr[] was undefined too, but am unable to reproduce this error.
What am I doing wrong?
The real issue I'm facing requires me to import an array and a struct to a class, and this class is imported to yet another bigger class, this last class is finally used by main. This is my best at reproducing it. I don't know how to fix this.
You should not include arrayFile.hpp inside your classFile.hpp. Include it only in classFile.cpp. Also, in mainfile.cpp (before main function) add line
extern int arr[];
This line tells the compiles that array of type int called "arr" will be defined in some other cpp file that will be linked together with mainfile.cpp.
Compile your program like this:
g++ -std=c++11 -c main.cpp classFile.cpp
g++ -std=c++11 main.o classFile.o
./a.out
First line compiles your files individually (creating main.o and classFile.o files)
Second line links them together creating one executable file (a.out)
Third line runs the executable file
Since adding new files makes this compilation process complicated, I suggest using a Makefile.
Broadly, it is not a good idea to define variables in a header file - assuming said header file will be included by multiple source files.
When you compile your project, the preprocessor handles "#include" statements by literally placing the content of the included header file in the file including it.
E.g.:
// foo.h
#ifndef FOO_H
#define FOO_H
typedef int myInt;
#endif
.
// main.cpp
#include "foo.h"
int main( int argc, char* argv[] )
{
return 0;
}
.
// preprocessor output
typedef int myInt;
int main( int argc, char* argv[] )
{
return 0;
}
This is a simplification - but good enough for illustrative purpose.
So what's happening in your example?
arrayFile.hpp is included by classFile.hpp which is included by classFile.cpp and mainfile.cpp. It may be helpful to consider the include-tree:
arrayFile.hpp
|
classFile.hpp
/ \
classFile.cpp mainfile.cpp
Think about what I said RE: replacing includes with the included file content and see if you don't agree when I say that classFile.cpp and mainfile.cpp both end up with a definition of your arr array.
What happens next when you're compiling your project? The compiler compiles your source code - specifically, the preprocessor output - to object files. E.g. the preprocessed classFile.cpp becomes classFile.o and the preprocessed mainfile.cpp becomes mainfile.o.
Finally, object files (or the libraries they are archived into) are linked to form your executable.
When the linker tries to link classFile.o and mainfile.o it will discover that both have arr defined in them. Thus you get your multiple definition linker error - not a compiler error.
So: if a header file is included - directly or indirectly - by multiple source files, you'll run into linker errors if the header file defines variables. This is why, it is standard practice to declare variables in header files and define them in one source file.
Hope that helps.

C++ I have a function used in all my headers

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.

Using struct in different .cpp file

I have two .cpp files in one project, main.cpp and myfile.cpp
I have globaly defined struct mystruct in main.cpp, now I want to use this struct in myfile.cpp.
When I write mystruct in a header file and include in both cpp files I get an error, saying mystruct redefinition. How should I solve this problem.
If you are trying to share the definition of a struct among several compilation units (cpp files), the common way is this: Place the definition of your struct in a header file (mystruct.h). If the struct contains any methods (i.e. it is rather a class with all member public by default), you can implement them in mystruct.CPP file, or, if they're lightweight, directly within the struct (which makes them inline by default).
mystruct.h:
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
struct MyStruct
{
int x;
void f1() { /* Implementation here. */ }
void f2(); /* Implemented in mystruct.cpp */
};
#endif
mystruct.cpp
#include "mystruct.h"
// Implementation of f2() goes here
void MyStruct::f2() { ... }
You can use your struct in as many cpp files as you like, simply #include mystruct.h:
main.cpp
#include "mystruct.h"
int main()
{
MyStruct myStruct;
myStruct.x = 1;
myStruct.f2();
// etc...
}
If, on the other hand, you are trying to share a global instance of the struct across several compilation units (it's not absolutely clear from your question), do as above but also add
extern MyStruct globalStruct;
to mystruct.h. This will announce that an instance is available with external linkage; in other words that a variable exists but is initialized elsewhere (in your case in mystruct.cpp). Add the initialization of the global instance to mystruct.cpp:
MyStruct globalStruct;
This is important. Without manually creating an instance of globalStruct, you'd get unresolved-external linker errors. Now you have access to globalStruct from each compilation unit that includes mystruct.h.
You should move the common struct to a header file and include that header in both files. Any other solution is a workaround.
The problem is that you basically have the same code twice as a result if you see an include as just a import of the code.
You can use #ifdef to fix it, see http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html
Declaration and definitions are two different things. For your case, you are allocating space for your structure in main.cpp. In your header, you should use the extern modifier for your struct so that all files that include the header file will look in the global namespace for the structure. Hope it helps.
The standard C/C++ approach:
// source.h
Put all struct, class, typedef, macro definitions, extern variable declaraltions
// source.cpp
Implement the class, functions, define global/external variables
// main.cpp, and other parts of program
#include"source.h"
You should define structure in the header file only, you should remove definition from main.cpp
May be you can give more information about what is the layout of your project.
Going by the guess, probably your problem can be either of the two:
you want forward declaration of struct.
using include guards to prevent redefinition.
See the following link for how to handle both:
http://www.adp-gmbh.ch/cpp/forward_decl.html
The header files also use include guards, so you can figure out what exactly can solve your problem.
If you want to share any variable between multiple cpp files, you should declare it in header as extern. And without extern in one of that c++ files.
If you don't do it, it'll lack at linking, because multiple objects would have variable with same name. Instead when using extern one object would have this variable and other objects link it.
The header is where you declare what your struct will consist of (probably a common.h file included by main.cpp and myfile.cpp):
struct MyStruct {
int messageID;
int tempVariable;
};
In your main.cpp, this is where you actually use the struct:
void someFunction() {
struct MyStruct tempStruct;
// do something with it
tempStruct.messageID = 1;
}
Don't put the definition of your struct in both your main.h and main.cpp - or you will get a redefinition error!
Also, don't include the cpp file - include the header file (e.g. common.h). Without knowing more about the structure of your program, it is hard to provide better information.