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.
Related
I am practicing using multiple files for C++ in Code::Blocks. I have three files, two source files named main.cpp and Cat.cpp, and a header file named Cat.h. Though I declare a function designed to output text in Cat.h, the implementation in the main function returns the error "'speak' was not declared in this scope."
I tried researching the error, but that was tricky because it's such a general error that can occur for a wide variety of reasons. I tried carefully checking for syntax errors or improper #include statements in my code, but I can't find anything.
This is in my main.cpp file:
#include <iostream>
#include "Cat.cpp"
#include "Cat.h"
using namespace std;
int main()
{
speak();
return 0;
}
this is my Cat.h file:
#ifndef CAT_H_INCLUDED
#define CAT_H_INCLUDED
void speak();
#endif
and this is my Cat.cpp file:
#include <iostream>
#include "Cat.h"
using namespace std;
void speak(){
cout << "Meow!!" << endl;
}
I am expecting speak() to run, but the error says it is not declared in this scope.
I'm trying to learn how to utilize header files in C++ projects, so I made .cpp files containing simple functions to make sure I'm doing all the declaring and including correctly.
Everything worked fine when I only had one set of .cpp and .h files, but when I try to add more I get errors.
To start with, in my project I had:
helloworld.cpp
#include "helloworld.h"
#include <iostream>
#include <cstdio>
using namespace std;
int HelloWorld() {
puts("Hello, World!");
cout << "Hello, World!" << endl;
return 0;
}
helloworld.h
#ifndef HELLOWORLD_H_INCLUDED
#define HELLOWORLD_H_INCLUDED
int HelloWorld();
#endif /* HELLOWORLD_H_INCLUDED */
main.cpp
#include "helloworld.h"
#include <iostream>
using namespace std;
int main(){
HelloWorld();
return 0;
}
Which built with no errors and ran correctly.
Next I tried adding a second .cpp and .h file, which created building errors.
pointers.cpp
#include "pointers.h"
#include <iostream>
using namespace std;
int Pointers() {
int x = 1;
int *ptr_a = &x;
cout << *ptr_a << endl;
return 0;
}
pointers.h
#ifndef POINTERS_H_INCLUDED
#ifndef POINTERS_H_INCLUDED
int Pointers();
#endif /* POINTERS_H_INCLUDED */
and modified main.cpp:
#include "helloworld.h"
#include "pointers.h"
#include <iostream>
using namespace std;
int main(){
HelloWorld();
Pointers();
return 0;
}
Now when I try to build, I get an error saying there are multiple definitions of main -- one in main.cpp, and the other in pointers.cpp.
Even more oddly, if I make a new project and do the exact same thing but reverse the order in which I create the .cpp and .h files (i.e. pointers first then helloworld), it builds and runs correctly with just the pointers files but runs into the same error when adding helloworld files, saying that the multiple exceptions of main are in main.cpp and helloworld.cpp.
I figure it must have something to do with Eclipse itself, but I don't know what the exact issue is.
Does anyone know what might be going on?
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
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.
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.