Reputation: 29
define strInterface in interface.h
// interface.h
#ifndef INTERFACE_H_
#define INTERFACE_H_
const char* strInterface = "the difference between char* and char array";
#endif
in the OneUsing class, strInterface string is called
// oneUsingInterface.h
#ifndef ONEUSINGINTERFACE_H_
#define ONEUSINGINTERFACE_H_
class OneUsing
{
private:
int mData;
public:
OneUsing();
OneUsing(int a);
void print();
};
#endif // ONEUSINGINTERFACE_H_
// oneUsingInterface.cpp
#include "oneUsingInterface.h"
#include "interface.h"
#include <iostream>
using namespace std;
OneUsing::OneUsing()
{}
OneUsing::OneUsing(int a)
{
mData = a;
}
void OneUsing::print()
{
cout<<"mData: "<<mData<<" strInterface: "<<strInterface<<endl;
}
in the main.cpp, interface.h is included as strInterface is called directly; it also includes oneUsingInterface.h as the OneUsing instance will be created.
//main.cpp
#include <iostream>
#include "interface.h"
#include "oneUsingInterface.h"
using namespace std;
int main()
{
cout<<strInterface<<endl;
OneUsing* pObject = new OneUsing(5);
pObject->print();
}
Now, the issue arising:
g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra -c .//main.cpp
g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra -c .//oneUsingInterface.cpp
g++ -I../boost_1_52_0/installation/prefix/include -I../boost_1_52_0/installation/prefix/lib -g -Wall -Wextra main.o oneUsingInterface.o -o main
oneUsingInterface.o:(.data+0x0): multiple definition of `strInterface'
main.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
However, if the strInterface is defined like this, there's no problem then:
// interface.h
#ifndef INTERFACE_H_
#define INTERFACE_H_
const char strInterface[] = "the difference between char* and char array";
#endif
Could some guys tell me more detail about the difference between char*
and char[]
in this case?
PS: we often declare the global variable with extern
keyword in header file, and we define it in someone's implementation file.
Upvotes: 1
Views: 145
Reputation: 1276
You have two different types here:
First, const char* strInterface
is a pointer to a constant character, and therefore you are creating a pointer of the same name in the global scope in two different compilation units making the linker complain about that. Note, that you could make the pointer point to something totally different later in the code. The pointer itself is mutable; the string it points to is immutable.
Second, const char strInterface[]
is an array of constant characters, which is created locally for each compilation unit, therefore the linker finds multiple definitions of that string which don't clash. This constant is immutable.
Upvotes: 1
Reputation: 792777
Namespace scoped variables that are declared const
have internal linkage by default so you can have such a variable with the same name defined in multiple translation units without causing a link error.
This variable is not const
, so it will have external linkage which means that only one such definition can exist in any program:
const char* strInterface = "...";
The const
version would be:
const char* const strInterface = "...";
This is const
because there is no distinction between the const`ness of an array and the constness of its elements. (IIRC there is some formal ambiguity about this fact in the standard.) You can have one such definition per translation unit in a program.
const char strInterface[] = "...";
Upvotes: 1
Reputation: 92341
The difference is that const char strInterface[]
defines a constant. Constants are local to each file they are included in. You will get a separate copy in each file.
The pointer const char* strInterface
points to constant data, but the pointer itself is not a constant. So by default it is visible to other translation units.
Upvotes: 2