Multiple definition of a const char*
Asked Answered
F

3

11

I get the above message linker error for a global

const char* HOST_NAME = "127.0.0.1";

I don't think that I have compiled some files twice but here's my definition of the files anyway.

main.cpp

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include "connection.hpp"

connection.cpp

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "connection.hpp"

connection.hpp

#ifndef __connection__
#define __connection__
#include <unistd.h>
#include <netinet/in.h>

const int BUFFSIZE = sysconf(_SC_PAGESIZE);             //Define page size
const char* HOST_NAME = "127.0.0.1";                    //Local host
//Definition of a class
#endif

Any help?

Flophouse answered 3/7, 2014 at 15:58 Comment(5)
Obviously the name HOST_NAME is also defined in one of the headers you include. Put the definition of HOST_NAME in a namespace.Bowens
I thought of that too but I used other names e.g. LOL and had the same issue.Flophouse
Why not make HOST_NAME const so it will get internal linkage?Minutes
I think it's const alreadyFlophouse
@BillyGrande: HOST_NAME is not const. It points to const data. You're looking for const char * const HOST_NAME.Rahm
D
41

You use wrong declaration for your string. You need to make your string a constant, since constants may be defined in several compilation units. This is why compiler does not report the same error for BUFFSIZE: BUFFSIZE is const, so it may be defined several times in different compilation units. But HOST_NAME is not const, so it is reported. HOST_NAME will be const if you change its declaration to

const char* const HOST_NAME = "127.0.0.1"; 

Then the error should disappear.


[C++11: 3.5/3]: 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,
  • a variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage; or
  • a data member of an anonymous union.

This effectively makes the constant "local" to each translation unit in which it is defined, removing the opportunity for conflict.

Dyadic answered 3/7, 2014 at 16:7 Comment(5)
Ohhh, now I get it. The pointer was const but not the data. So now we make the data const as well and it works. Thanks a lot guys!! :)Flophouse
Actually it was the other way round - your pointer was non-const pointer to const data. I made it const pointer to const data.Dyadic
For how many years I have been programming, the const char* means the pointer will be constant and not the data.Crystlecs
@SauerVoussoir sorry to say but you are wrong. You can find detailed explanation at #1143762Dyadic
Oh my bad, I did not see you corrected @BillyGrande since you did not mentioned himCrystlecs
S
2

don't think that I have compiled some files twice

Nevertheless that's exactly what happened. You have compiled connection.hpp several times, each time you have # included it into some translation unit.

Either add static to the declaration, or add extern to it, delete the = somestring portion, and provide a definition in exactly one source file.

Stereotypy answered 3/7, 2014 at 15:58 Comment(0)
M
2

You have included "connection.hpp" to both connection.cpp and main.cpp. Therefore it (const char* HOST_NAME = "127.0.0.1";) is defined in 2 cpp files.

Maugre answered 3/7, 2014 at 16:2 Comment(5)
No header guards does not prevent it.Maugre
Is that a problem? They are two different cpp files.Flophouse
@SujithGunawardhane: You're correct. I misread the question as having one cpp file and 2 header files.Rahm
Yes, If you define some variable in a header file it goes to all the cpp files which included.Maugre
You can get this solved by defining "const char* HOST_NAME = "127.0.0.1";" in one cpp file and "extern const char* HOST_NAME;" in the other cpp file. Then you can access it from both cpp files.Maugre

© 2022 - 2024 — McMap. All rights reserved.