Two files using each other funtions - how to solve it? - c++

I have two headers with source files, lets say file1.h, file1.cc and file2.h, file2.cc. They use each others functions, for example:
file1.h:
void test1();
file2.h:
void test2();
file1.cc:
#include "file1.h"
#include "file2.h"
void test1() {
do_something();
test2();
}
file2.cc:
#include "file1.h"
#include "file2.h"
void test2() {
do_something_else();
test1();
}
I get the problem, the dependancy is mutual and we cant compile one file without having another compiled. How to solve this problem?

Modify the files to remove the double recursion.
Use some code to prevent double inclusion of your .h files (I have used #pragma once at the top of the .h files)
optionally, add a main.cpp to call the functions
provide code for do_something()
compile using . g++ *.cpp -o main
Great question!
Here are the files:
// main.cpp
//
#include <iostream>
#include "file1.h"
#include "file2.h"
int main() {
test2();
std::cout << "Hello, World!" << std::endl;
return 0;
}
// file1.cpp
#include "file1.h"
#include "file2.h"
#include <iostream>
void do_something() {
std::cout << "Just hit do_something" << std::endl;
}
void test1() {
do_something();
// test2(); // Do not use double recursion.
}
// file1.h
#pragma once
void do_something();
void test1();
// file2.cpp
#include "file1.h"
#include "file2.h"
void test2() {
do_something();
test1();
}
// file2.h
#pragma once
void test2();

The best answer is don't design your code like that! This introduces a "circular dependency," which immediately makes your code fragile. Additionally, the way you have your example written describes a double-recursive function (A calls B which calls A), and since there is no terminating condition, is unbounded! As you can see, this can lead to some very unmanageable circumstances.
Let's forego good engineering practices for a while. How you described both headers & source files is adequate and can be built with the following command:
g++ file1.cc file2.cc -o libCoupledRecursiveExample.so
This is where things become difficult: through the build instructions alone, you can't actually detect the dependency! Good static code checkers can detect these circumstances and warn you, but when you use a lazy compiler (like g++ without flags), it's easy to sneak by code like this that won't generate any warnings.

Related

C++ undefined reference to class (1 header 2 cpp's)

I am reading a book (C++ for dummies) as well as watching youtube videos to learn how to code. I am currently struggling with very simple class functions.
Main.cpp
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include "Test.h"
using namespace std;
int x;
int main(int nNumberofArgs, char* pszArgs[])
{
combat fight;
cout << x;
fight.dodmg();
cout << x;
return 0;
}
Test.h my header file with the class
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
int dodmg();
void zero_out();
private:
int x;
};
#endif // TEST_H_INCLUDED
Test.cpp class functions
#include "Test.h"
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20
}
I tried to make this very simplistic just to figure out how to work a class.
I included a lot of #includes just to try and make sure it wasn't something stupid like I needed strings.
I am not sure why but the videos I watched simply had the header say
ifndef TEST_H (of their respective code, mine has an _INCLUDE as well, I tried deleting it and it still didn't work.
My unfortunate errors
on line 14 of main.cpp fight.dodmg(); it says
\Beginning_Programming-CPP\Playing_with_class\main.cpp|14|undefined reference to `combat::dodmg()'|
then below that
||error: ld returned 1 exit status|
How are you compiling this? I think this is an issue because you arent compiling your Test.cpp file. If you arent already, try compiling with the command:
g++ main.cpp Test.cpp -o MyProgram
UPDATE:
Few things, you dont have a closing statement to your #ifndef directive in Text.h, you will need a constructor to set the value of x so i added one to the combat class also you were missing a semicolon in the zero_out function. I added comments to all the lines I changed.
Okay try this:
Test.h
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
combat(); // added constructor
int dodmg();
void zero_out();
private:
int x;
};
#endif // closed #ifndef
Text.cpp
#include "Test.h"
combat::combat() // implemented constructor
{
x = 20;
}
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20; // added ';'
}
Hope this helps,
Final edit: I dont think you really need your header guards in this scenario, you could remove the "#ifndef, #define, and the #endif" lines and not see a difference really
It sounds like you provide the wrong arguments for the compiler. Your header file (Test.h) simply provides signatures for the methods, but the implementations are given in the source file (Test.cpp).
This is an important part of writing C++ (or C) code. Your compiler does not automatically search for source files, so you need to tell it where to look, e.g.:
g++ -std=c++11 main.cpp Test.cpp -o main

How to use global variables in multiple .cpp files?

I have this simple program which tries to print my global variable in a separate file. I'm using the Visual Studio 2013 professional IDE.
print.h
#ifndef PRINT_H_
#define PRINT_H_
void Print();
#endif
print.cpp
#include "print.h"
#include <iostream>
void Print()
{
std::cout << g_x << '\n';
}
source.cpp
#include <iostream>
#include <limits>
#include "print.h"
extern int g_x = 5;
int main()
{
Print();
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
I get a compiler error error C2065: 'g_x' : undeclared identifier.
I've searched through this forum and was unable to find anyone else having my problem. I've tried re-declaring my global variable in the separate .cpp file with no success. As you can see, I've included the necessary header guards and assigned my global variable the extern keyword. This is my first time testing global variables in multiple files. Obviously I'm missing something simple. What do I need to change or add to make my program work?
EDIT: I found this topic useful in understanding the difference between extern and the definition of a global variable.
The compiler is compiling print.cpp. It knows nothing about source.cpp while it is compiling print.cpp. Therefore that g_x that you placed in source.cpp does you absolutely no good when print.cpp is being compiled, that's why you get the error.
What you probably want to do is
1) place extern int g_x; inside of print.h. Then the compiler will see g_x when compiling print.cpp.
2) in source.cpp, remove the extern from the declaration of g_x:
int g_x = 5;
Move your global declaration to a common header, like common.h:
#ifndef COMMON_H_
#define COMMON_H_
extern int g_x; //tells the compiler that g_x exists somewhere
#endif
print.cpp:
#include <iostream>
#include "print.h"
#include "common.h"
void Print()
{
std::cout << g_x << '\n';
}
source.cpp:
#include <iostream>
#include <limits>
#include "print.h"
#include "common.h"
int g_x;
int main()
{
g_x = 5; //initialize global var
Print();
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
In other .cpp files, you can access g_x including the common.h header.
extern int g_x;
belongs to .h, and you need to add
int g_x =5;
to some of .cpp.

How does chain of includes function in C++?

In my first.cpp I put #include second.h.
As a consequence first.cpp sees the content of second.cpp.
In second.cpp I put #include third.h.
My question is: will first.cpp see the content of the third.cpp?
ADDED
I thought that if I include second.h I will be able to use functions declared in second.h and described (defined, written) in the second.cpp. In this sense the content of the second.cpp becomes available to the first.cpp
When using #include the actual file content of that file appears as part of the input for the compiler. This means that first.cpp will appear to the compiler as if it has second.h and third.h inside it. The source code in second.cpp and third.cpp are separate files [1], that need to be compiled separately, and they are all combined at the linking stage at the end of compilation.
[1] unless second.h contains #include "second.cpp"or something to that effect - this is not typically how to do this, however, so I'm going to ignore that option.
You can think about #include as a simple text insert. But if you include second.h you "see" second.h and not second.cpp.
With a concrete example
//second.h
#ifndef SECOND_INCLUDED
#define SECOND_INCLUDED
void foo();
#endif
//first.cpp
#include second.h
void bar()
{
foo();//ok
}
void no_good()
{
wibble();//not ok - can't see declaration from here
}
//third.h
#ifndef THIRD_INCLUDED
#define THIRD_INCLUDED
void wibble();
#endif
//second.cpp
#include second.h
#include third.h
void foo()
{
wibble();//ok in second.cpp since this includes third.h
}
The cpp file that includes a header file sees what's in the header file, not in other source files that include the header.
first.cpp will see the constent of third.h (and you will be able to use in first.cpp functions declared in third.h and defined in third.cpp). Suppose, you have in your test.h:
#include<iostream>
using namespace std;
and in your test.cpp:
#include "test.h"
int main()
{
cout << "Hello world!" << endl;
}
As you see, cout declared in <iostream> is visible in test.cpp.

Use jmp_buf in multiple file

For clearly, please view my sample
I have two files: main.cpp and myfunction.h
This is main.cpp
#include <setjmp.h>
#include <myfunction.h>
int main()
{
if ( ! setjmp(bufJum) ) {
printf("1");
func();
} else {
printf("2");
}
return 0;
}
This is myfunction.h
#include <setjmp.h>
static jmp_buf bufJum;
int func(){
longjum(bufJum, 1);
}
Now, I want my screen print "1" and then print "2", but this code is uncorrect!
Please, help me!
Thank you so much!
If you want to have it in multiple files, then you need to create two source files, not a single source file and a header file
myfunction.cpp:
#include <setjmp.h>
extern jmp_buf bufJum; // Note: `extern` to tell the compiler it's defined in another file
void func()
{
longjmp(bufJum, 1);
}
main.cpp:
#include <iostream>
#include <setjmp.h>
jmp_buf bufJum; // Note: no `static`
void func(); // Function prototype, so the compiler know about it
int main()
{
if (setjmp(bufJum) == 0)
{
std::cout << "1\n";
func();
}
else
{
std::cout << "2\n";
}
return 0;
}
If you are using GCC to compile these files, you can e.g. use this command line:
$ g++ -Wall main.cpp myfunction.cpp -o myprogram
Now you have an executable program called myprogram which is made from two files.
I don't know anything about setjmp, but you have at least one mistake in your code:
-#include <myfunction.h>
+#include "myfunction.h"
You have a non-inline function defined in a .h file. While not illegal, this is pretty much always wrong.
You have a static global variable defined in a .h file. While not illegal, this is pretty much always wrong.

Problem with using functions in 1 cpp file in another

I have 1 cpp file with main().
It relies on structs and functions in another (say, header.hpp).
The structs are defined in header.hpp, along with function prototypes. The functions are implemented in header.cpp.
When I try to compile, I get an error message saying:
undefined reference to `see_blah(my_thing *)`
So to give an overview:
header.hpp:
#ifndef HEADERDUR_HPP
#define HEADERDUR_HPP
struct my_thing{
int blah;
};
int see_blah(my_thing*);
#endif
header.cpp:
#include "header.hpp"
int see_blah(my_thing * thingy){
// ...
}
main.cpp:
#include <iostream>
#include "header.hpp"
using namespace std;
int main(void)
{
thinger.blah = 123;
cout << see_blah(&thinger) << endl;
return 0;
}
I have no idea what I'm doing wrong, and I can't find any answers. Thanks for any answers, they are very much appreciated!
You should be aware that you're missing a semi-colon at the end of your structure definition. This means it's folding the two (supposedly separate) parts together and that you're not getting the function prototype as a result.
The following compiles fine (after fixing a couple of other errors as well):
// main.cpp
#include <iostream>
#include "header.hpp"
using namespace std; // <- not best practice, but irrelevant here :-)
int main(void)
{
my_thing thinger; // <- need this!
thinger.blah = 123;
cout << see_blah(&thinger) << endl;
return 0;
}
// header.cpp
#include "header.hpp"
int see_blah(my_thing * thingy){
// ...
}
// header.hpp
#ifndef HEADERDUR_HPP
#define HEADERDUR_HPP
struct my_thing{
int blah;
}; // <- see here.
int see_blah(my_thing*);
#endif
with:
g++ -o progname main.cpp header.cpp
gcc actually gave an error with that code you posted so I'm not certain why your compiler didn't. That command line above is also important - if you're compiling and linking in one step, you need to provide all required C++ source files (otherwise the linker won't have access to everything).
Your code is fine. You're just compiling it wrong. Try:
g++ main.cpp header.cpp
You need to:
#include "header.hpp"
in your *main.cpp file.
If you have included header.hpp, than probably you haven't link it(header.cpp) with main.cpp. What environment are you using(g++ or VC++)?
Edit:for linking in g++ you must write:
g++ main.cpp header.cpp -o program
Also you are missing semicolon in the end of your struct!
thinger.blah = 123; should be along the lines of:
my_thing thinger = { 123 };
in addition to issues other posters have mentioned. please, update your example so it compiles.
You are missing a semi colon at the end of your structure definition and mixing it with the method.