C++ using booleans across multiple files - c++

//main.cpp
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldEvents = false;
void worldReactions(bool world);
int main (int argc, const char * argv[])
{
while (true)
{
if (worldAction == true)
{
worldEvents = true;
worldReactions(worldEvents);
}
else
{
worldEvents = false;
break;
}
}
return 0;
}
//1.cpp
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldAction;
//header
#ifndef worldActions_h
#define worldActions_h
bool worldAction = true;
#endif /* defined(__asdf_Story__worldActions__) */
When ever extern is used I get linking errors and when it's not I get redefinition errors. How can I fix this so I can use a global boolean?

You use extern bool worldAction; in the header and put the definition in the cpp file.

You are currently compiling a global worldAction into each file which includes your header. If more than one file includes the header or (as in your source file) any other file defines a variable with the same name, you'll get linker errors.
To fix this, change your header to declare the variable only
#ifndef worldActions_h
#define worldActions_h
extern bool worldAction;
#endif /* defined(__Julian_Story__worldActions__) */
and define/initialise it in your source file
#include <iostream>
#include "worldActions.h"
using namespace std;
bool worldAction = true;

use keyword externlike extern bool worldAction; & put definition bool worldAction = true in .cpp file

Related

undefined reference of a function but already defined in header

main cpp
#include "utility.h"
#include <windows.h>
int main()
{
do
{
changeColor();
system("pause");
} while (true);
}
utility cpp
#include "utility.h"
#include "variables.h"
#include <windows.h>
namespace utility
{
void changeColor()
{
if (var::colorCounter == 0)
{
system("color af");
}
else if (var::colorCounter == 1)
{
system("color cf");
}
else if (var::colorCounter == 2)
{
system("color df");
}
else if (var::colorCounter == 3)
{
system("color 6f");
}
else
{
system("color 9f");
var::colorCounter = -1;
}
var::colorCounter++;
}
}
utility header
#ifndef utility
#define utility
void changeColor();
#endif
variables
#ifndef variables
#define variables
namespace var
{
inline int colorCounter{};
}
#endif
idk whats causing it to produce the changeColor() to not define what should i do? also is may coding right?
There are many problems with your code which are shown through the comments in the modified program below.
main.cpp
#include "utility.h"
int main()
{
utility::changeColor();//used utility:: because you've to be in the scope of namespace utility to call function changeColor()
}
utility.h
#ifndef UTILITY_H //USED INCLUDE GUARDS
#define UTILITY_H
namespace utility {
void changeColor(); //this function declaration is now inside the utitliy namespace
}
#endif
variables.h
#ifndef VARIABLES_H //USED INCLUDE GUARDS
#define VARIABLES_H
namespace var
{
//NOTE the extern keyword here instead of inline keyword
extern int colorCounter; //this is a nondefininig declaraiton for colorCounter.
}
#endif
variables.cpp
#include "variables.h"
namespace var
{
int colorCounter = 0; //this is definition of colorCounter
}
The output of the above program can be seen here.
Modifications
Some of the modifications that i made include:
In main.cpp, you have to be in the scope of the namespace utility to call function changeColor(). This is achieved using utility::.
In utility.h, header guards are used. This is a recommended practice.
In utility.h, the function declaration for changeColor is placed inside the namespace utility.
In variables.h, extern keyword is used instead of inline keyword to make the declaration of colorCounter a declaration that is not a definition. This essentially means, colorCounter has external linkage.
In variables.cpp, the variable colorCounter has been initialized with value 0.
Note
If you still want to use inline instead of extern you can do so from C++17 and onward as can be seen here. So if you use inline your program will work for C++17 and onwards. But if you use extern as in my above code, then your program will work in all C++ versions. You can choose whichever version you want.

Defining member variable in header without class definition

I've got two files, list.cpp and Header.h. Segments of the files are below. I know that if the header file is for a class, it is setup different. E.g.
class MyClass
{
public:
void foo();
int bar;
};
However, since I'm not really working with a class here (correct me if I'm wrong), am I not able to declare things under public: and private like below?
Also, if I were to place the global variable rescan in the header file as a member variable, below the function definitions, only the main function can see the variable. Why is it not within the scope of the other functions?
list.cpp:
#include <boost/algorithm/string.hpp>
#include <vector>
using namespace std;
vector<int> results;
bool rescan;
int main()
{
vector<vector<string>> list;
int success = readFile(list);
vector<vector<string>> bad = findMe(list);
system("pause");
return 0;
}
vector<vector<string>> findMe(vector<vector<string>> find)
{
rescan = true;
}
Header.h:
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
std::vector<std::vector<std::string>> findMe(std::vector<std::vector<std::string>>);
#endif
EDIT: I tried this in my header file:
public:
bool rescan;
But I got "syntax error: 'public'
If you want your global to be visible in other translation units (TU) (other files), you have to declare them extern in those other TUs:
Header.h:
// Include guard omitted
extern bool rescan; // Declaration
file.cpp
#include "Header.h"
bool rescan = false; // Definition
// ...
file2.cpp
#include "Header.h" // To see extern bool rescan;
void foo()
{
rescan = true;
}
// ...

Error already defined

Hi i just created a sample class and using it in main but i am getting already defined error.
sample.h
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
#endif
sample.cpp
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
#include <iostream>
#include "sample.h"
using namespace std;
int main(void)
{
int test = count;
return 0;
}
Link error:
main.obj : error LNK2005: "int count" (?count##3HA) already defined in sample.obj
if u see above class i am using #ifndef and #define, actually there things will declare data once thought we include in many places.could some one explain me clearly why its giving that link error.
Remember that #include literally means "add the contents of this file here".
Include guards only protects against a file's content being included more than once per file it's included in.
When the preprocessor has done its preprocessing, this is what your compiler sees:
sample.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
using namespace std;
int main(void)
{
int test = count;
return 0;
}
As you can see, there are two definitions of count, one in each file (formally, "translation unit").
The solution is to have a declaration of the variable in "sample.h"
extern int count;
and have the one and only definition in sample.cpp:
int count = 10;
(And you should not put using namespace std; in a header.)
To make a global variable like that visible everywhere:
blah.h
extern int count;
blah.cpp
int count(10);
Include guards only guard against including the same header file multiple times, not against multiple definitions. You should move your variable in a cpp file in order to not violate the ODR, or use internal linkage or declare it external and define it somewhere once. There are multiple solutions depending on the use of that variable.
Notice that I'm ignoring the fact that you probably meant int sample::Get() in the sample.cpp file
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample() // ??
{
return 10;
}
You have either to declare variable count as having internal linkage as for example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
namespace
{
int count = 10;
}
//...
#endif
(the above internal declaration valid in C++ 2011) or
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
static int count = 10;
//...
#endif
Or to declare it as having external linkage but define it only once in some module. Fpr example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
extern int count;
//...
#endif
#include "sample.h"
int count = 10;
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
Otherwise the compiler will issue an error that variable count is defined more than once that is that more than one compilation unit (in this case sample.cpp and main.cpp) contain the variable definition.

Calling a C function from C++, "no matching function" error

I've defined the following header file (in C), left out the function implementation since thise aren't needed:
#ifndef FFMPEG_MEDIAMETADATARETRIEVER_H_
#define FFMPEG_MEDIAMETADATARETRIEVER_H_
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int setDataSource(AVFormatContext** pFormatCtx, const char* path);
#endif /*FFMPEG_MEDIAMETADATARETRIEVER_H_*/
In C++, I defined my second header file:
#ifndef MEDIAMETADATARETRIEVER_H
#define MEDIAMETADATARETRIEVER_H
using namespace std;
extern "C" {
#include "ffmpeg_mediametadataretriever.h"
}
class MediaMetadataRetriever
{
public:
MediaMetadataRetriever();
~MediaMetadataRetriever();
int setDataSource(const char* dataSourceUrl);
};
#endif // MEDIAMETADATARETRIEVER_H
In, mediametadataretriever.cpp I defined the following function:
int MediaMetadataRetriever::setDataSource(
const char *srcUrl)
{
// should call C function
AVFormatContext* pFormatCtx;
return setDataSource(&pFormatCtx, srcUrl);
}
When I try to compile this (C++) project in Eclipse I get a "No matching function call..." error related to:
return setDataSource(&pFormatCtx, srcUrl);
If I comment out the call, the code compiles fine:
int MediaMetadataRetriever::setDataSource(
const char *srcUrl)
{
return 0;
}
This appears to be a linking issue, does anyone know what I'm doing wrong?
setDataSource in that context is the name of the member function. To invoke the free function, try fully qualifying its name:
return ::setDataSource(&pFormatCtx, srcUrl);
// ^^

namespaces in c++

How to use namespaces in C++ where it is accessible in different header files. Lets say I have this below:
// namespaces
#include <iostream>
using namespace std;
namespace first
{
int var = 5;
}
namespace second
{
double var = 3.1416;
}
int main () {
cout << first::var << endl;
cout << second::var << endl;
return 0;
}
and I want t use var variable from first namespace in another class... that is defined and implemented in another .h and .cpp file?
//server.h
#ifndef SERVER_H
#define SERVER_H
class server{
server();
//blah
};
#endif SERVER_H
//server.cpp
server::server()
{
first::var = 3;
}
is this possible to do it like this? When I try I get an error that says that my namespace is not defined. And if i put using namespace first in the .h or .cpp it says there is no namespace called first...
Besides having the namespace in a header, you need to make the variable extern:
//header.h
namespace first
{
extern int var;
}
//implementation.cpp
#include "header.h"
namespace first
{
int var = 5;
}
If the variable is not extern, a symbol will be generated wherever the header is included, and you'll get linker errors.
If you don't want the extra header, you can just declare the variable as extern in the same namespace where you want to use it:
//server.cpp
namespace first
{
extern int var;
}
server::server()
{
first::var = 3;
}
Note some answers might claim that you should make the variable static. This is wrong, although it will compile, as then the variable won't act as a global. A copy of it will be created for every translation unit.