ask a question about C++

Y

Yanxiong

I have three files: file1.h, file1.cpp, test_main.cpp, and the source
code as follow:

file.h
#ifndef _FILE1_H_
#define _FILE1_H_
#include <cstdio>

/*********************************
Here is the problem, if I use const char *STR = "Test const char *";
the Compiler tell "fatal error LNK1169: one or more multiply defined
symbols found.", if I use static const char *STR = "Test const char
*"; or const char STR[ ] = "Test const char *"; it will be OK. I don't
know why??? If you know,please tell me,thanks very much.
*****************************/
const char *STR = "Test const char *";

void print(const char *str);
#endif


file.cpp
#include "file1.h"
void print(const char *str)
{
printf("%s\n", str);
}


test_main.cpp
#include "file1.h"
int main()
{
print(STR);
return 0;
}
 
I

Ian Collins

I have three files: file1.h, file1.cpp, test_main.cpp, and the source
code as follow:

file.h
#ifndef _FILE1_H_
#define _FILE1_H_
#include<cstdio>

/*********************************
Here is the problem, if I use const char *STR = "Test const char *";
the Compiler tell "fatal error LNK1169: one or more multiply defined
symbols found.", if I use static const char *STR = "Test const char
*"; or const char STR[ ] = "Test const char *"; it will be OK. I don't
know why??? If you know,please tell me,thanks very much.
*****************************/
const char *STR = "Test const char *";

try

const char* const STR = "Test const char *";

Note the second const.

const char* STR is a pointer to const char.

const char* const STR is a const pointer to const char.
 
S

Stuart Redmann

Yanxiong said:
I have three files: file1.h, file1.cpp, test_main.cpp, and the source
code as follow:

file.h
#ifndef _FILE1_H_
#define _FILE1_H_
#include <cstdio>

/*********************************
Here is the problem, if I use const char *STR = "Test const char *";
the Compiler tell "fatal error LNK1169: one or more multiply defined
symbols found.", if I use static const char *STR = "Test const char
*"; or const char STR[ ] = "Test const char *"; it will be OK. I don't
know why??? If you know,please tell me,thanks very much.
*****************************/
const char *STR = "Test const char *";

void print(const char *str);
#endif


file.cpp
#include "file1.h"
void print(const char *str)
{
printf("%s\n", str);
}


test_main.cpp
#include "file1.h"
int main()
{
print(STR);
return 0;
}

The definition (note that the term "definition" is used in the C++
sense: "definition" = "declaration" + "initialization") of a variable
in a header file will almost always lead to _linker_ errors (hence the
error name LNKxxx; the _compiler_ is quite happy with your code ;-).
This is because of C++'s One Definition Rule, google for that. To
overcome your problem you should declare STR in your header file using
the keyword "extern", and initialize it in one of your cpp-files
(probably file1.cpp).

Regards,
Stuart
 
A

Andrew Poelstra

The definition (note that the term "definition" is used in the C++
sense: "definition" = "declaration" + "initialization") of a variable
in a header file will almost always lead to _linker_ errors (hence the
error name LNKxxx; the _compiler_ is quite happy with your code ;-).
This is because of C++'s One Definition Rule, google for that. To
overcome your problem you should declare STR in your header file using
the keyword "extern", and initialize it in one of your cpp-files
(probably file1.cpp).

Alternately, he could qualify his declaration with the 'static'
keyword, which would scope it to the current translation unit,
and not export any symbols.

That would avoid linker errors, though it would create a new
copy of the variable for each transation unit.

In general, though, it is best simply to not define (or even
declare, if possible) variables in header files.
 
Y

Yanxiong

Alternately, he could qualify his declaration with the 'static'
keyword, which would scope it to the current translation unit,
and not export any symbols.

That would avoid linker errors, though it would create a new
copy of the variable for each transation unit.

In general, though, it is best simply to not define (or even
declare, if possible) variables in header files.

why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks
 
I

Ian Collins

why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks

Because one's a constant and the other is not.
 
Y

Yanxiong

why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks

Because one's a constant and the other is not.

I know the different between const char *STR and const char * const
STR, but why I use const char *STR, the compiler report multiply
defined? That's mean why const char* STR is wrong, but const char *
const STR is OK?
 
Ö

Öö Tiib

On 04/24/10 11:36 PM, Yanxiong wrote:
why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks
Because one's a constant and the other is not.

I know the different between const char *STR and const char * const
STR, but why I use const char *STR, the compiler report multiply
defined? That's mean why const char* STR is wrong, but const char *
const STR is OK?

Because if STR is const then it is with internal linkage unless
explicitly or previously declared otherwise. So there word static is
not needed. When it is not const you need the word static to indicate
it is with internal linkage. If you leave it to be with external
linkage then each translation unit that includes your header will have
it defined and linker will hate multiple copies of same symbol with
external linkage.
 
Y

Yanxiong

On 04/24/10 11:36 PM, Yanxiong wrote:
why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks
Because one's a constant and the other is not.
I know the different between const char *STR and const char * const
STR, but why I use const char *STR, the compiler report multiply
defined? That's mean why const char* STR is wrong, but const char *
const STR is OK?

Because if STR is const then it is with internal linkage unless
explicitly or previously declared otherwise. So there word static is
not needed. When it is not const you need the word static to indicate
it is with internal linkage. If you leave it to be with external
linkage then each translation unit that includes your header will have
it defined and linker will hate multiple copies of same symbol with
external linkage.


So, you mean the problem is caused by external linkage? But as you
said, the const and static are all with internal linkage, so why const
char STR[] (internal linkage?) and static char *STR (internal linkage)
is OK, but const char *STR (internal linkage) caused multiple defined?
What's the different between const char STR[] and const char *STR in
linkage?
 
P

Paul Bibbings

Yanxiong said:
On 4月25æ—¥, 上åˆ4æ—¶52分, Ian Collins <[email protected]> wrote:
On 04/24/10 11:36 PM, Yanxiong wrote:
why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks
Because one's a constant and the other is not.
I know the different between const char *STR and const char * const
STR, but why I use const char *STR, the compiler report multiply
defined? That's mean why const char* STR is wrong, but const char *
const STR is OK?

Because if STR is const then it is with internal linkage unless
explicitly or previously declared otherwise. So there word static is
not needed. When it is not const you need the word static to indicate
it is with internal linkage. If you leave it to be with external
linkage then each translation unit that includes your header will have
it defined and linker will hate multiple copies of same symbol with
external linkage.


So, you mean the problem is caused by external linkage? But as you
said, the const and static are all with internal linkage, so why const
char STR[] (internal linkage?) and static char *STR (internal linkage)
is OK, but const char *STR (internal linkage) caused multiple defined?

const char *STR does *not* have internal linkage as you suppose here.
Note that the const, here, refers to the thing pointed to and not to the
pointer itself. To attain internal linkage for STR you need either:

const char *const STR; (*pointer* is now const; internal linkage)

or (deprecated, or soon to be):

static const char * STR; (internal linkage for non-const pointer)
What's the different between const char STR[] and const char *STR in
linkage?

Since there is no sense in which it is possible to have an array refer
(or point) to another array, an array is considered const if its
elements are const. This is not the case for pointers, which do not
take on constness from the constness of the thing pointed to.

Regards

Paul Bibbings
 
Y

Yanxiong

Yanxiong said:
On 04/24/10 11:36 PM, Yanxiong wrote:
why I use const char *STR in header file is wrong, but use const char
STR[] is OK ? I want to know the reason, thanks
Because one's a constant and the other is not.
--
Ian Collins
I know the different between const char *STR and const char * const
STR, but why I use const char *STR, the compiler report multiply
defined? That's mean why const char* STR is wrong, but const char *
const STR is OK?
Because if STR is const then it is with internal linkage unless
explicitly or previously declared otherwise. So there word static is
not needed. When it is not const you need the word static to indicate
it is with internal linkage. If you leave it to be with external
linkage then each translation unit that includes your header will have
it defined and linker will hate multiple copies of same symbol with
external linkage.
So, you mean the problem is caused by external linkage? But as you
said, the const and static are all with internal linkage, so why const
char STR[] (internal linkage?) and static char *STR (internal linkage)
is OK, but const char *STR (internal linkage) caused multiple defined?

const char *STR does *not* have internal linkage as you suppose here.
Note that the const, here, refers to the thing pointed to and not to the
pointer itself.  To attain internal linkage for STR you need either:

   const char *const STR;    (*pointer* is now const; internal linkage)

or (deprecated, or soon to be):

   static const char * STR;  (internal linkage for non-const pointer)
What's the different between const char STR[] and const char *STR in
linkage?

Since there is no sense in which it is possible to have an array refer
(or point) to another array, an array is considered const if its
elements are const.  This is not the case for pointers, which do not
take on constness from the constness of the thing pointed to.

Regards

Paul Bibbings



Thank all of you very much. Due to your patient answers, I know the
reason finally. That's because const char *STR has external linkage,
const char STR[] and static const char *STR have internal linkage. So,
if I use const char *STR, each unit includes this header will have it
defined, and cause multiply defined.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top