Define namespace scope function - c++

I want to define public function in namespace scope (not in Class - this works)
Basically I want use it like for example the:
std::chrono::milliseconds(16)
I've tried many setups but here is the recent one:
TimeX.h
#ifndef TIMEX_H
#define TIMEX_H
namespace timee{
int now(int z);
}
#endif
TimeX.cpp
#include <chrono>
#include "TimeX.h"
using namespace timee;
int now(int z){return 4;}
Main.cpp
#include <iostream>
#include "TimeX.h"
using namespace timee;
int main(int argc, char** argv){
long c = now(2);
std::cout << "c" << c <<std::endl;
return 0;
}
And this gives me following error:
Main.obj : error LNK2019: unresolved external symbol "int __cdecl timee::now(int)" (?now#timee##YAHH#Z) referenced in function _SDL_main
What is the problem with this? It's confusing. Why linker tells me that this is referenced in _SDL_main? I use SDL library but what it has to do with my function?
Second problem related with this code.
And also one additional question (if it is not easy to answer I would start new topic). I'm using timee for namespace name because I've had an error telling that time name is used somewhere already Error C2757. I guess it is probably nested somewhere. How can I find out where it is used and is it possible to use the name anyway? I can't imagine how compiler have a problem in figuring out what I want to use.

You have to define the function like
int timee::now(int z){return 4;}
Or you could write for example this way
#include <chrono>
#include "TimeX.h"
namespace timee
{
int now(int z){return 4;}
}
Otherwise in the cpp module there is declared (and defined) another function with the same name in the global namespace
#include <chrono>
#include "TimeX.h"
using namespace timee;
int now(int z){return 4;}
That is these two definitions
int timee::now(int z){return 4;}
int now(int z){return 4;}
define different functions. The first one declares (and defines) the function in the namespace timee while the second one declares (and defines) another function with the same name in the global namespace.
As for the name time then it is defined in the global namespace and corresponds to the C standard function time. For example the header <chrono> can in turn include the header <time.h> where the name time is declared.

Related

Declare variable in namespace, define it in main, make it visible to all other files [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
Using C++14, I'm trying to define a variable in a namespace where commonly used variables are stored (App::Common). The main function should be the one that sets it, since it gets set to argv[0]. Meanwhile I need the variable to be visible by all other classes/files. But I get the linker error shown below. Also, ideally I would like the variable to be const where only the main function would set it once.
common.hpp
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
main.cpp
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
client.hpp
#include "common.hpp"
class Client {
public:
void printAppPath();
};
client.cpp
#include <iostream>
#include <string>
#include "common.hpp"
#include "client.hpp"
void Client::printAppPath() {
std::cout << App::Common::appPath << std::endl;
}
I get the following error by the linker:
ld: main.o: in function `main':
main.cpp:(.text.startup.main+0x25): undefined reference to `App::Common::appPath[abi:cxx11]'
ld: Client.o: in function `Client::printAppPath()':
Client.cpp:(.text...): undefined reference to `App::Common::appPath[abi:cxx11]'
This
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
contains only declaration of the variable appPath without its definition.
Here
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
there is used the assignment operator to assign a value tp the variable appPath as if it were already defined. However actually its definition does not yet exist.
You can define the variable in any module in any enclosing namespace of the namespace Common or inside the namespace. For example you could define it in client.cpp like
std::string App::Common::appPth;
You are mixing definition and assignment, which are two different things for a variable:
a declaration for a variable x tells your compiler that there exists somewhere a variable named x;
a definition for a variable x tells your compiler that it needs to reserve some space for this variable x, and that the variable x will live at this location;
an assignment assigns a value to a variable.
For a variable, a declaration is usually a definition:
void foo() {
int a; // Declaration AND Definition!
}
...except when the variable is marked as extern, since extern explicitly tells the compiler that this variable is defined elsewhere. In your case, this:
namespace App::Common { // C++17 style
extern std::string appPath;
}
...is a declaration, but this:
namespace App::Common { // C++17 style
std::string appPath;
}
...would be a definition (and also a declaration), and this:
int main(int argc, char *argv[]) {
App::Common::appPath = std::string(argv[0]);
}
...is an assignment.
You should not define appPath in a header such as common.hpp, otherwize, you will have multiple definitions of the same variable (one for each .cpp file that includes your common.hpp) and the program will fail to compile.
What you want is a single definition for your program, and the only way to obtain it is to define App::Common::appPath once-and-for-all in a .cpp file. You can define it in main.cpp if you want:
#include <string>
#include "common.hpp"
#include "client.hpp"
// Definition:
std::string App::Common::appPath;
int main() {
// Assignment:
App::Common::appPath = argv[0];
}
You need definition:
in Common.cpp:
namespace App{
namespace Common{
std::string appPath;
}
}

g++ how to solve warning "used but never defined"? (not static or inline)

I have come across a strange compile error that I cannot make sense of. Firstly the error refers to the function as if it was in an anonymous namespace, however it is in fact inside namespace database. Secondly the "used but never defined" statement suggests that the compile requires me to define the function from within the header. The function is in fact declared in a separate implementation file. However the function is neither static nor inline so I am at a loss as to why it requires a definition in the header. It is a requirement that this piece of code is strictly compliant, because of this I have compiled with both -Wall -Werror. I have also included a shortened version of my source code for clarification.
Note: This question is different from other similar questions asked here in that it does not involve static or inline functions.
Error:
In file included from src/main.cpp:6:0:
include/database.hpp:19:6: error: 'void {anonymous}::SetupSettings()' used but never defined [-Werror]
void SetupSettings();
^
cc1plus.exe: all warnings being treated as errors
main.cpp
#include <iostream>
#include "config.hpp"
#include "database.hpp"
int main() {
database::SetupSettings();
return 0;
}
database.hpp
#ifndef database
#define database
#include <iostream>
#include "config.hpp"
#include "sqlite/sqlite3.h"
namespace database {
extern sqlite3* settings_database;
void SetupSettings();
// ^^ Apparent warning here.
} // namespace database
#endif
database.cpp:
#include <iostream>
#include <vector>
#include "config.hpp"
#include "database.hpp"
#include "sqlite/sqlite3.h"
namespace database {
sqlite3* settings_database;
void SetupSettings() {/*More code here*/}
} // namespace database
The problem is caused by use of:
#ifndef database
#define database
After that,
namespace database { ...
is seen as
namespace { ...
i.e. an anonymous namespace.
You need to use a different include guard macro, such as:
#ifndef database_hpp
#define database_hpp

How do I use the same object across two classes?

I have a total of three classes...
1. Source.cpp (Where the main function is.)
2. Variables.h (Where I declared all my variables in, Variables.cpp is pretty much irrelevant)
3. Functions.cpp & .h (Where I make the functions to run in the main function in Source.cpp)
In main i have this
#include <iostream>
#include <cstdlib>
#include "Variables.h"
#include "Functions.h"
#include <ctime>
using namespace std;
Variables vari;
Functions func;
int main(){
cout << "\n\n>>> ";
cin >> vari.answer;
func.choiceChecker();
}
In Functions.cpp I have this
Variables vari;
void Functions::choiceChecker(){
if (vari.answer == 1){
scenario1();
}
else{
cout << "Failed";
}
}
I always get the output failed, instead of running the scenario1 function. I also get two errors.
1.Error 1 error LNK2005: "class Variables vari" (?vari##3VVariables##A) already defined in Source.obj C:\Users...\Desktop\Projects\ConsoleApplication1\ConsoleApplication1\Functions.obj ConsoleApplication1
2.Error 2 error LNK1169: one or more multiply defined symbols found C:\Users...\Desktop\Projects\ConsoleApplication1\Debug\ConsoleApplication1.exe ConsoleApplication1
I've tried using a new object in Functions.cpp, i get no errors but it doesn't get the same value from
cin >> vari.answer;
To use one global variable, you have to declare it once, then define it once (WhozCraig linked this question with its explanation).
The following should work in your situation:
Add extern Variables vari; in Variables.h (below the declaration of the Variables class or struct).
At the bottom of Variables.cpp add Variables vari;
In Functions.h you add #include Variables.h
In Source.cpp you remove #include Variables.h (because Functions.h already includes this)
Now you should be able to use vari in both Functions.cpp and Source.cpp.

Error: Class computer comp is already defined in computer.obj

I am currently playing with C++, and attempting to rebuild a Tic Tac Toe batch console game I made in C++, but have hit a wall, where I cannot figure out how to get rid of the error TicTacToe.obj : error LNK2005: "class computer comp" (?comp##3Vcomputer##A) already defined in computer.obj. I have tried removing the declaration of the function computer from the header, and the definition of the function in the C++, but that didn't fix the error. The only way I figured out how to remove this error was to remove the object name, which I kind of don't want to do. I used the example given on the website http://www.cplusplus.com/doc/tutorial/classes/ to set up the class computer. Any information you can provide on any errors that I currently have, or any functions I may not need are most definately welcome, as I am wanting to know much much more about C++.
CODE:
TicTacToe.cpp
// TicTacToe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include "computer.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
comp.Select();
Sleep(1000);
}
computer.cpp
#include "stdafx.h"
#include "computer.h"
#include <iostream>
using namespace std;
computer::computer()
{
}
computer::~computer()
{
}
void computer::Select()
{
}
computer.h
#pragma once
class computer
{
public:
computer();
~computer();
void Select(void);
} comp;
EXTRA INFO:
I am using Microsoft Visual Studio Professional 2013 on a laptop running Windows 7.
As you included header "computer.h" in both modules computer.cpp and TicTacToe.cpp then the both modules contain the same definition of object comp
pragma once
class computer
{
public:
computer();
~computer();
void Select(void);
} comp;
So the linker issues the error.
Define the object only in one cpp module. The header should contain only the class definition.
For example
computer.h
#pragma once
class computer
{
public:
computer();
~computer();
void Select(void);
};
TicTacToe.cpp
// TicTacToe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include "computer.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
computer comp;
comp.Select();
Sleep(1000);
}
You have to remove comp from the header file. Create the object in a cpp file like this:
computer comp;
You said you don't want to do that. If that causes some other problem for you then post a new question about that problem.
You are defining comp in the header, and so in every .cpp that includes that header, so you are breaking the One Definition Rule.
Instead you can declare it in the header:
extern computer comp;
And then define it in exactly one .cpp:
computer comp;
Which will still allow you to access it from any .cpp that includes the header.

Unresolved external symbol error while using vectors defined in a header file

I am new to C++. I had an unresolved external symbol error while using vectors and didn't know what was going wrong so I've replicated it here.
I am using MS Visual Studio 2011. The exact error is:
error LNK2001: unresolved external symbol "class std::vector > abc"
(?abc##3V?$vector#VmyClass##V?$allocator#VmyClass###std###std##A)
I have my class declaration in myClass.h:
#ifndef __MYCLASS__
#define __MYCLASS__
class myClass{
public:
int var;
myClass(void);
myClass (int k);
};
#endif
and my class definition in myClass.cpp:
#include"myClass.h"
myClass::myClass(void){
var=0;
}
myClass::myClass (int k){
var=k;
}
header.h :
ifndef __HEADER__
#define __HEADER__
#include<iostream>
#include<vector>
#include"myClass.h"
using namespace std;
extern std::vector<myClass> abc;
#endif
main.cpp :
#include <iostream>
#include <vector>
#include "myClass.h"
#include "header.h"
using namespace std;
int main(){
abc.push_back(myClass(5));
return 1;
}
This is where I get the unresolved external symbol error. Now I tried putting all of these in a single file and it compiled alright.
THE FOLLOWING FILE IS NOT INCLUDED IN THE ABOVE PROJECT.
#include<iostream>
#include<vector>
#include"myClass.h"
using namespace std;
class myClass{
public:
int var;
myClass(void){
var=0;
}
myClass (int k){
var=k;
}
};
int main(){
std::vector<myClass> abc;
abc.push_back(myClass(5));
return 1;
}
The solution has been given at What is an undefined reference/unresolved external symbol error and how do I fix it?
but I can't figure out how to implement it.
You do not have a definition for this vector:
extern std::vector<myClass> abc;
An extern declaration only tells the compiler that the object exists and it is defined somewhere. But you haven't defined it anywhere.
Add this at global namespace scope in one (and only one!) of your .cpp files:
std::vector<myClass> abc;
Actually, considering that you are not using abc from different translation units (i.e. .cpp files) you do not need the extern declaration at all. Just place your vector in main.cpp, since that is the only place where you are using it.
Also, avoid using directives, especially at namespace scope (since it easily leads to nasty name clashes with entities from the Standard Library):
using namespace std; // THIS IS BAD, DON'T DO IT
Considering that you are qualifying the names of entities from the std namespace already, you don't really need the above.
You declared abc as extern but you never provided definition for it.
Try add definition inside main.cpp:
#include <iostream>
#include <vector>
#include "myClass.h"
#include "header.h"
using namespace std;
std::vector<myClass> abc; //^^add this line
int main(){
abc.push_back(myClass(5));
return 1;
}
However, IMHO using extern here in your code seems useless. Meanwhile, I don't think it is good to name a header file as header.h.
You have abc as a local variable. It should be a global variable. Only then extern would work.
But if you only want to access it as a local variable from within main() and not from another compiled CPP file/object, then it is pointless to use an extern. The extern is only needed if the variable is global and to be accessed from another compiled CPP/object.