I have created header file abc.hpp which contains a namespace of multiple functions.
When I use single source file which includes the header and call the function defined in namespace it works well, but when I call the same function in project where I have to include this header in multiple places, compilation gives me multiple definition error.
My other files are created as library and get executed.
abc.hpp:
#ifndef __ABC_HPP__
#define __ABC_HPP__
namespace abc {
void sendtext(const char* msg)
{
create_context(mycontext);
send_context(create_context,msg)
}
void sendtextwitherrno(const char* msg, int errn)
{
create_context(mycontext);
send_context(create_context,msg, errn)
}
};
#endif
test.cpp:
#include"abc.hpp"
int main()
{
abc::sendtext("hello world");
abc::sendtextwitherrno("hello error no",140);
return 0;
}
You can treat header files as if they are copy-pasted into your implementation files. So by putting function definitions into your headers, those definitions appear in multiple translation units (roughly, compiler .cpp files). This is not allowed - how is the compiler supposed to tell between them if they end up different?
Usually you would have a .h/.cpp pair, with function declarations going in the .h, and function definitions going in the .cpp. This way the definition only appears once in your whole program.
I can split your code like this:
abc.hpp:
#ifndef __ABC_HPP__
#define __ABC_HPP__
// function **declarations**
namespace abc{
void sendtext(const char* msg);
void sendtextwitherrno(const char* msg, int errn);
}
#endif
abc.cpp:
#include "abc.hpp"
#include "context.hpp" // I guess this might be where create_context and send_context come from
// function **definitions**
namespace abc{
void sendtext(const char* msg){
create_context(mycontext); // not sure where mycontext is supposed to live?
send_context(create_context,msg)
}
void sendtextwitherrno(const char* msg, int errn){
create_context(mycontext);
send_context(create_context,msg, errn);
}
}
test.cpp:
#include "abc.hpp"
int main(){
abc::sendtext("hello world");
abc::sendtextwitherrno("hello error no",140);
return 0;
}
Another way is to mark the functions as inline - this tells the compiler you are deliberately repeating the function definition all over the place, and you'd better be sure the definition is always identical. How sure are you? Are there different macros or different compiler flags in place in different places the function is used?
Related
I'm trying to make a namespace and its members available globally however I am running into already defined errors.
Settings.h
#pragma once
#include "boost/property_tree/json_parser.hpp"
#include <string>
using json = boost::property_tree::ptree;
namespace Settings {
extern std::string settingsPath;
extern json settings;
extern void init();
extern void readSettings();
extern void writeSettings();
};
Settings.cpp
#pragma once
#include "Settings.h"
using json = boost::property_tree::ptree;
namespace Settings {
void init() {
}
void readSettings() {
}
void writeSettings() {
}
};
I am forward declaring the Settings namespace and members and using extern. I have no idea what I'm doing wrong. Please could someone point out the error here.
Thanks
Edit: The actual error messages:
Error LNK2005 "class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > Settings::settingsPath" (?settingsPath#Settings##3V?$
basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) already defined in
AmalgamService.obj Amalgam F:\Dropbox\CPP\Visual Studio Projects\Amalgam\Amalgam\
main.obj 1
And repeat for all members of the namespace. The Settings.h is #includeed in main.cpp and AmalgamService.cpp
You seem to be including Settings.cpp in another file. Do not include .cpp files. This results in duplicate definitions. This also means that #pragma once in .cpp files is useless.
You need to keep in mind that #include is just a glorified copy&paste tool. When you #include a file, that file is literally being copy&pasted into the spot of the #include statement. So including a .cpp file means you will get multiple definitions of everything defined in that .cpp file.
Furthermore, you don't have to use extern when declaring functions. Functions are extern by default, unless you say otherwise.
Variables are extern by default too, however you need to use extern as a way to declare them without defining them:
extern int var; // declaration
int var; // definition
Functions don't need that, because you can declare them by omitting their body:
void func(); // declaration
void func() { } // definition
You are allowed to declare things multiple times, which is why you can #include header files (like .h, .hpp) in multiple files. But you are not allowed to define things multiple times, which is why you can't #include non-header source files.
in my code I have the following header files:
Global.h:
#ifndef GLOBAL_H_
#define GLOBAL_H_
#include <mutex>
namespace
{
std::mutex outputMutex;
}
#endif
Test.h:
#ifndef TEST_H_
#define TEST_H_
#include"Global.h"
#include<string>
#include<iostream>
class TestClass
{
std::string name;
public:
TestClass(std::string n):name{n}{}
void operator()()
{
for (int i=0;i<30;++i)
{
std::lock_guard<std::mutex> lock(outputMutex);
std::cout<<name<<name<<name<<name<<name<<name<<name<<std::endl;
}
}
};
#endif
Test2.h is actually equal to Test1.h, only containing a class called "TestClass2" instead of "TestClass".
My main.cpp looks like this:
#include<iostream>
#include <thread>
#include "Global.h"
#include "Test.h"
#include "Test2.h"
using namespace std;
int main()
{
TestClass obj1("Hello");
TestClass2 obj2("GoodBye");
thread t1(obj1);
thread t2(obj2);
t1.join();
t2.join();
}
If I run the program like this I get the expected output:
HelloHelloHelloHelloHelloHelloHello
or
GoodByeGoodByeGoodByeGoodByeGoodByeGoodByeGoodBye
So far so good. But when I put the definition of the ()-operator of Test.h and Test2.h in source files Test.cpp and Test2.cpp:
(Test.cpp, same for Test2.cpp):
#include "Test.h"
#include"Global.h"
void TestClass::operator()()
{
for (int i=0;i<30;++i)
{
std::lock_guard<std::mutex> lock(outputMutex);
std::cout<<name<<name<<name<<name<<name<<name<<name<<std::endl;
}
}
and accordingly remove the definition from the header-files: void operator()(); I suddenly start getting occasional outputs like this:
GoodByeHelloGoodByeHelloGoodByeHelloGoodByeHelloGoodByeHelloGoodByeHelloGoodByeHello
I don't know why the lock with the mutex variable outputMutex doesn't work any more, but I assume it has something to do with two versions of the variable being created, but I'd love to get a professional explanation. I'm using Eclipse with Cygwin.
This is a mixture of undefined behavior and anonymous namespaces.
First this:
namespace {
std::mutex outputMutex;
}
this is an anonymous namespace containing the mutex outputMatrix. A different outputMatrix exists in every source file, as it has a different name.
That is what anonymous namespaces do. Think of them as "generate unique guid here for each cpp file that builds this". They are intended to prevent link-time symbol collisions.
class TestClass {
std::string name;
public:
// ...
void operator()() {
// ...
}
};
this is an (implicitly) inline TestClass::operator(). Its body is compiled in each compilation unit. By the ODR the body must be the same in every compilation unit, or your program is ill-formed, no diagnostic required. (methods defined inside a class definition are implicitly inline, with all that baggage).
It uses a token from an anonymous namespace. This token has a different meaning in each compilation unit. If there is more than one compilation unit, the result is an ill-formed program with no diagnostic required; the C++ standard places no restrictions on its behavior1.
In this particular case, the same compilation unit was chosen for operator() from TestClass and TestClass2. So it used the same mutex. This is not reliable; a partial rebuild could cause it to change, or the phases of the moon.
When you put it into its own .cpp file, it was no longer implicitly inline. Only one definition existed, but they where in separate compilation units.
These two different compilation units got a different outputMatrix mutex.
1 The most common effect of violating that particular rule is that the linker picks one implementation based on arbitrary criteria (that can change from build to build!), and silently discards the rest. This is not good, as innocuous changes to the build process (adding more cores, partial builds, etc) can break your code. Don't violate the "inline functions must have the same definition everywhere" rule. This is just the most common symptom; you are not guaranteed to have anything this sensible happen.
I have the following header:
#ifndef MY_H_
#define MY_H_
namespace A {
void f() {
// do something
}
}
#endif
However, when I compiled, I got errors like multiple definition of A::f(). I thought that the #ifndef check is enough to avoid duplicate definitions in 1 translation unit. Maybe I miss something?
Thanks in advance.
Add inline specifier before the function definition:
#ifndef MY_H_
#define MY_H_
namespace A {
inline void f() {
// do something
}
}
#endif
You should declare functions in the header file but define them in your cpp file. If you include this header file from multiple translation units (which is most probable), then there will be multiple implementations available for different translation units. Each of your cpp files that includes this header will have an implementation of f. This way, if f is to be called, it is ambiguous. By putting the implementation into a cpp file, it can be linked and used that way. But there is only one implementation available which makes it unambiguous.
So, your header file should be:
#ifndef MY_H_
#define MY_H_
namespace A
{
void f(); // declaration only
}
#endif
and your source file:
#include "myHeader.h"
namespace A
{
void f()
{
// some implementation
}
}
Then, you should be fine. You would usually do that with all of your functions. The only exceptions are inline functions/methods or templates but this is beyond the scope of this question.
I'm trying to set up some logging functions for an OpenGL application. GLFW offers the option to register a callback function that is called whenever an error takes place, but because it is a C library it demands that the function be written in C style, i.e. outside of a class. Because of that, I put my logging functions into a namespace defined in file log.h.
#ifndef LOG_H
#define LOG_H
#include <fstream>
namespace gllog{
#define GL_LOG_FILE "gl.log"
bool restart_gl_log(){
//...
}
bool gl_log (const char* message, const char* filename, int line){
//...
}
void glfw_error_callback (int error, const char* description){
//...
}
};
#endif
Even though I added include guards, whenever I include this file from two different files, I get errors like the following:
CMakeFiles/gl4tuts.dir/extended_initialisation/ExtendedInitialisation.cpp.o: In function `gllog::glfw_error_callback(int, char const*)':
ExtendedInitialisation.cpp:(.text+0x340): multiple definition of `gllog::glfw_error_callback(int, char const*)'
CMakeFiles/gl4tuts.dir/hello_triangle/HelloTriangle.cpp.o:HelloTriangle.cpp:(.text+0xa10): first defined here
I'm building with CMake.
What could be the reason? Could the absence of a class be related?
Include guards protect you from including the same header file more than once while compiling the same .cpp file. They don't stop you from including the same header file more than once while compiling different .cpp files -- in fact they're commonly used to make the same class available in different compilation units.
The compiler is not complaining, by the way, the linker is.
I have a function that is the same across all my header files and main.cpp if I define it in main.cpp will they all be able to use it once they are included or will they have a compiler issue?
Still new to this whole header file business. Thanks in advance.
In the header file (myfunction.h), you need to have only declaration of the function:
int foo(int param);
In the main.cpp (or any other cpp file - better choice would be myfunction.cpp - just make sure definition is included in exactly one file!) file, you need to have definition of the function:
int foo(int param)
{
return 1;
}
In all other source (cpp) files where you're using function foo, just include myfunction.h and use function:
#include "myfunction.h"
void someotherfunction()
{
std::cout << foo(1) << std::endl;
}
Compiler only needs to see declaration of the function before it is used. Linker will connect definition of the function with the places you've used the function. If you forget to write definition in main.cpp file, you will not get compiler, but a linker error. It may be worth of mentioning that compiler is compiling each cpp file separately, and linker's job is to combine all compiler object files and to produce final output file. On most setups, linker will be called automatically after compiling, so you may not be familiar with it.
If you include entire function definition in the header file, that definition will be compiled in each translation unit where header file is included, and you will get multiple symbol definition linker error, or something similar - that's why you need to include only declaration of the function inside header file. However, there are exceptions for this - for example, you may declare your function inline - other answers explain this approach.
So, now myfunction.h contains the function declaration:
#ifndef MY_FUNCTION_H
#define MY_FUNCITON_H
// declaration
int myfunction();
#end if
myfunction.cpp contains the function definition:
int myfunction()
{
return 4;
}
Now, in file1.cpp and in file2.cpp you want to use this function, so you're including myfunction.h:
// file1.cpp
#include "myfunction.h"
// somewhere in the file
void foo()
{
std::cout << myfunction();
}
... and in the second file:
// file2.cpp
#include "myfunction.h"
// somewhere in the file
void bar()
{
/// ...
std::cout << myfunction();
}
Header files in C and C++ are a language artifact. They are the consequence of the fact, that C and C++ can be implemented as a single-pass compiler. In contrast, Pascal - for example - has a two-pass compiler, that skips over unknown entities during the first pass, and fills in the missing bits in a second pass. Consequently, in C and C++ every type, object, and method must be declared before it can be used. This is the main responsibility of header files.
Header files are expanded into any file that includes them. In other words: The preprocessor replaces the statement #include "foo.h" with the contents of the file "foo.h". With this being the case you need to be careful to not violate the single definition rule: An entity must not be defined more than once.
To meet both requirements you have two options: Declare and define the function in the header, using the inline keyword, or declaring it in the header only, and defining it in another compilation unit.
The following code illustrates both solutions:
// foo.h
inline void foo() {
// Method is implemented in this header file.
// It is marked 'inline' to prevent linker errors
// concerning multiply defined symbols.
...
}
Delaration in header only, implementation in another compilation unit:
// foo.h
extern void foo();
// foo.cpp (or another compilation unit)
void foo() {
...
}
Regardless of which solution you go with, you can use foo() from any compilation unit. If you want to use it from "main.cpp" the code would look something like this:
// main.cpp
#include "foo.h"
int main() {
foo();
}
So you have a function which is used in all your header files, why don't you make a utility.h which keeps track of these types of functions and inline the functions in the .h ?
Declare the function prototype in a custom header file:
int add(int a, int b);
let say header file name is myfunction.h and include it wherever you need the function.
now you can define a function on another.cpp or main.cpp
int add(int a, int b){
return a+b;
}
include your custom header file like this:
#include "myfunction.h"
remember your main.cpp and other cpp files and the new header file should be in the same path.
If you have two files:
main.cpp
#include "func.h"
int main(){
hello();
std::cout<<" world!\n";
return 0;
}
& func.h
#ifndef FUNC_H
#define FUNC_H
#include <iostream>
void hello(void){
std::cout<<"hello";
}
#endif
iostreams objects and functions e.t.c will work fine from within main.cpp.
This posts answers sum up #ifndef pretty well if you would like to know more.