C++ #include only loading one namespace? - c++

probably a stupid question but I can't get this to work for some reason. I'm quite new to C++ so I think I might have some misunderstanding somewhere.
graphics.hpp:
#ifndef Airport_game_hpp
#define Airport_game_hpp
#include <SDL2/SDL.h>
namespace graphics {
namespace gl{
static SDL_Window *mainWindow;
static SDL_GLContext mainContext;
bool initGL();
bool destroyGL();
}
}
#endif
game.hpp:
#ifndef Airport_game_hpp
#define Airport_game_hpp
namespace game{
void render();
}
#endif
main.cpp:
#include <iostream>
#include "graphics/graphics.hpp"
#include "game/game.hpp"
int main(int argc, char* argv[])
{
std::cout << "Starting application \n";
if (!graphics::gl::initGL()){
std::cout << "OpenGL initialization failed \n";
return false;
}
//Test
game::render(); //This line says: Use of undeclared identifier "game"
graphics::gl::destroyGL();
std::cout << "Exit successful \n";
}
If I swap the order of the #include-s on main.cpp the "game" namespace is seen but not the "graphics" one. It seems like it only sees one at a time. What am I misunderstanding here?
Thanks!

You're using the same include guard in both headers. Ideally the include guard should reflect the name of the module or header, but you should at least change one of them, in order to make them both unique.

Both headers use the same include guard: Airport_game_hpp. This means that the second header to be included will be ignored, since its guard has already been defined by the first.
Change the guard for graphics.hpp to Airport_graphics_hpp and, in general, make sure your guard names are unique.

Related

Understanding Preprocessor Directives in C++ as a beginner

I recently began learning C++. As a programmer coming from Python, I've noticed some general similarities when it comes to how certain things in C++ do the same thing over in Python.
One question I had is understanding Preprocessor directives. I/O Stream seems to be a common one to use in beginner programs.
Is #include effectively the same thing as import in Python, or is it completely different than importing "modules"?
C++ did not have modules until the latest standard (C++20). #include is not the same as import in the languages that support modules. Instead, it is a source code - level inclusion of a "header" file. Usually, the headers only contain declarations but not definitions of what you are "importing". The definitions are contained in compiled libraries that are added by the linker.
Congrats on diving in to C++, you're going to have many more questions and confusions coming from Python, especially if you use some of the newer standards (like C++11/14/17/20).
That aside, answering your question directly:
Is #include effectively the same thing as import in Python or is it completely different than importing "modules."
I won't speak to C++20 modules as that functionality is not fully supported across the various compilers and that is not your question. Unfortunately the answer is not a simple yes or no, it's kind of both.
In C and C++, the #include pre-processor directive essentially does a "copy-paste" of whatever file you #include before it does the compilation stage. This allows you to separate large chunks of code into easier to manage files and still reference the code in said file.
In Python/C#/Java and various other languages, you don't #include a file you want to access the classes and functions of, you import the namespace or module you wish to reference and the JIT compiler "knows" which file that module or namespace is in, allowing you to use the functionality of the code in that file.
Python and C++ don't "build" the code in the same way and thus don't reference parts of the source code in the same way.
To illustrate this point more succinctly, take the following C++ code:
file: fun.hpp
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
file: main.cpp
#include <iostream>
#include "fun.hpp"
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
In the above code, when we #include "fun.hpp", what the C++ pre-processor does before compiling is essentially "copy-and-paste" the code in iostream and fun.hpp, so what actually gets compiled is something like the following:
file: main.cpp
// #include <iostream> <- this is replaced with the whole std::iostream file
// not putting that here as it's huge.
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
It is because of this "copy-paste" that you also need to have include guards, because if you did something like the following:
file: main.cpp
#include <iostream>
#include "fun.hpp"
#include "fun.hpp"
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
This code won't compile because you'll get errors about various items being redeclared since what gets compiled is the following:
file: main.cpp
// #include <iostream> <- this is replaced with the whole std::iostream file
// not putting that here as it's huge.
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
// #include "fun.hpp" <- this is replaced with this:
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
int main(int argc, char* argvp[])
{
if (fun::get_fun() == FUN_NUM) {
std::cout << "Fun!" << std::endl;
}
return FUN_NUM;
}
To protect from the double inclusion and redefinition, you can simply do something like the following:
file: fun.hpp
#if !defined(FUN_HPP)
#define FUN_HPP
#define FUN_NUM 1
namespace fun
{
int get_fun()
{
return FUN_NUM;
}
}
#endif // define FUN_HPP
So unless you pass FUN_HPP as a pre-processor define to the compiler, then FUN_HPP will not be defined until the file is #include'd once, then any other times it's included, FUN_HPP will already be defined and thus the pre-processor will not include the code again, ridding the problem of double-definitions.
So where your question is concerned, the #include directive in C++ is somewhat like the import directive in Python, but mostly to the effect that they both allow the file you are putting that directive in, to access code more directly from that import or #include.
I hope that can add a little clarity.

Eclipse C++ multiple main error only when using multiple headers

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?

Good modularity in C++ using #define

As the title says I'm looking for a good way to do modularity in C++ using #define. Let me explain.
I have a simple settings header file like such:
//Settings.h
define HTTP
And a include file:
//include.h
#include <iostream>
using namespace std;
#ifdef HTTP
#include "HTTPStuff.cpp"
#endif
Main file:
//Main.cpp
#include "Include\Includes.h"
int main(int argc, char *argv[]) {
string res = HTTP_POST_REQUEST("localhost", "/script.php", "data=data1");
cout << res << endl;
cin.get();
}
The function HTTP_POST_REQUEST is inside HTTPStuff.cpp
This however makes a lot of errors popup when trying to run the program.
Like "missing ';' before identifier 'response'", and it all just seems weird to me.
If HTTP is defined, then include HTTPStuff.cpp which contains HTTP_POST_REQUEST.
I must be missing something, but what?

Object creation error

I am a complete c++ noob. Start to learn it from the java. So, after hard study with some tutorials, I ended up with this class named Token:
#include "Token.h"
#include <iostream>
using namespace std;
//int Token::frequency = 0;
Token::Token() {
// TODO Auto-generated constructor stub
frequency=0;
tok = "hey i am created";
cout << tok << endl; // prints !!!Hello World!!!
}
Token::~Token() {
// TODO Auto-generated destructor stub
}
The header for this class is this:
#ifndef TOKEN_H_
#define TOKEN_H_
#include <string>
class Token {
std::string tok;
int frequency;
public:
Token();
virtual ~Token();
};
#endif /* TOKEN_H_ */
It looks like in the tutorial, all right. The error is when I called it in my main class:
#ifndef TOKEN_H_
#define TOKEN_H_
#include <iostream>
using namespace std;
int main() {
Token myToken;
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
#endif /* TOKEN_H_ */
The error says :
Tokenizer.cpp:15:8: error: expected ‘;’ before ‘myToken’
Whyyy? I looked up the tutorials and answers here, it looks like I am doing it right? What is going on? And, if you see that I did some other crap, pls tell me, I will be thankful, I just came from Java to C++...
You have #ifndef TOKEN_H_ around your main function, which makes no sense. That #ifndef is called a header guard, and it's used to protected headers from being included multiple times. Your main function should go into a source file (.c or .cpp or the like). You do not need header guards in source files since they aren't included from other source files.
You need your main.cpp file to be like this:
#include <iostream>
#include "token.h"
// other stuff, like the using namespace
int main() { /* then your main function. */ }
Actually, most of your source files will follow this sort of pattern. This is the same pattern your Token.cpp file is built with.
You need to include the actual header for your class
#include "Token.h"
That way the class definition is available and you can declare an instance of Token in main
These are header/include guards, you don't need them in your main file
#ifndef TOKEN_H_
#define TOKEN_H_
You are not incluiding the token header #include "token.h", thus, the compiler think that Token myToken; is a definition not a declaration, also you don't need the header guards
remove the #ifndef guards from the main.c file. Also include the Token.h header in main.

C++ Namespace ofstream Won't Write

I'm working on making a game in C++. I have declared a Constant namespace used for global values that I need access to throughout the program. In there I have an ofstream for debugging purposes (yeah, I know it's not "constant" but it fits best there), which outputs only when it feels like it. I was able to make a small program demonstrating the problem. I apologize for it being spread across 4 files, but it is important, I promise.
main.cpp:
// Include necessary files
#include "test.h"
#include "constants.h"
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
// Start of program
Constant::outstream.open("test.txt");
// ...
// Do stuff
// Output debugging info
Test test;
test.print("Test", Constant::outstream);
// ...
// Do other stuff
// End of program
Constant::outstream.close();
return 0;
}
constants.h:
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
#include <fstream>
namespace Constant
{
static ofstream outstream;
}
#endif
test.h:
#ifndef _TEST_H
#define _TEST_H
#include <string>
#include <fstream>
#include "constants.h"
class Test
{
public:
void print(string str, ofstream& out);
};
#endif
test.cpp:
#include "test.h"
using namespace std;
void Test::print(string str, ofstream& out)
{
out << "out: " << str << endl << flush; // Works
Constant::outstream << "Constant::outstream: " << str << endl << flush; // Doesn't
}
In the test.cpp file, the out << ... line works as it should, while the Constant::outsream << ... line doesn't do anything even though I'm passing Constant::outstream as the out parameter! I don't see any reason why these two lines should be in any way different.
Before posting this, I tried putting test.cpp's code in test.h, just to have less files for the question, and was amazed to see it work. If I copy-paste the Test::print() function into test.h (whether inside or out of the class Test { ... }), then both output commands work correctly. the problem only occurs if Test::print()'s implementation is in a separate file.
It seems like any references to Constant::outstream simply don't work in class cpp files (no compile error, just nothing happens). It works in main.cpp and in class header files, but any class cpp file it seems not to. Unfortunately, this is a big program I'm writing so pretty much every class has its own cpp implementation file, and that's really the one place I need to use this ofstream. Does anyone know the reason for this?
Thanks in advance,
Doug
Constant::outstream has internal linkage, thus a separate instance is created for each translation unit. In short, Constant::outstream in test.cpp and main.cpp are two different variables.
§3.5.2 A name having namespace scope (3.3.6) has internal linkage if it is the name of
— a variable, function or function template that is explicitly declared static; or,
On the other hand, static class members would be visible throughout the program.
So, if you would write
struct Constant
{
static ofstream outstream;
}
instead of
namespace Constant
{
static ofstream outstream;
}
it would work.
However, note that the class must have external linkage; e.g. you should not put in in anonymous namespace.