Click here to Skip to main content
15,886,857 members
Please Sign up or sign in to vote.
2.43/5 (4 votes)
See more:
I have a header file with " const char * lp = 'abc' ";and be included multi-times(i.e located more than 1 file).But the vs compiler complains "have defined in xxx.obj"(like this.)

But I know that the const var is internal by default. And I have tried that the "const int n =1" is OK within the same header file.

Why not " const char * lp " ? thanks in advance.
Posted
Comments
Sergey Alexandrovich Kryukov 16-Oct-14 23:34pm    
What do you mean "internal"? Opposite to "extern"? This C++ terminology is not very clear, it's related to separate compilation. Don't look at names of things, look at what happens. Yes, you cannot compile this time multiple times in the same compilation unit. What would it mean?
—SA
Aescleal 21-Oct-14 7:11am    
Your English is a bit clumsy but it looks like you've been researching what's supposed to happen with const objects so you don't deserve the downvotes.

Here's a quick clue which the others seem to have missed... when something is complaining about an obj file it's not the compilation that's the problem, it's the linker that's having a whinge.

You're correct that const implies internal linkage - i.e. the name of the variable shouldn't escape from the translation unit it's defined in. If you define two const objects with the same name in two translation units everything is hunky dory and works fine. As you've noticed it works with const ints, so what's wrong with the pointer type you want to use?

The problem is that that when you write:

C++
const char *lp = "Urgle...";


lp isn't constant. You can modify lp to your heart's content - what you can't do is modify *lp. If you really want to make lp a constant so you can have things with the same name in different translation units you have to make the pointer itself a constant:

C++
const char * const lp = "Urgle...";


will do the trick.

While it's not a book on C++ I'd recommend Peter Van Der Linden's book Expert C Programming: Deep C Secrets for how to decode and write declarations in C and C++. C++ is a bit different as to how it treats const but it'l still help you get your brain around C++'s declaration syntax.

Edit: Edited for punctuation and a bit of highlighting I missed
 
Share this answer
 
v2
Comments
CPallini 21-Oct-14 7:31am    
5.
Aescleal 21-Oct-14 8:21am    
Thankyou - nice to know I'm appreciated when I stick my head over the parapet every once in a while :-)
Richard MacCutchan 21-Oct-14 9:00am    
Anyone who has read your previous posts will certainly appreciate your input. No matter how many times I read it, I always forget about the double const.
nv3 21-Oct-14 8:28am    
My 5 as well; I have missed that point indeed.
«_Superman_» 23-Oct-14 1:03am    
Beautifully explained. My 5.
What you "know" is wrong. Who told you that? You apparently don't understand what you are talking about.

Forget for a minute about include files. The are included before compilation. Imagine that they are all substituted with their texts (this is what really happens before compilation). Then you will have only CPP files. Each one is compiled separately into some object file; you will have as many object files as CPP files. Then the executable code is created by linking together all object files. So, each CPP file is compiled into a separate compilation unit.

How one can use variables or constants across compilation units. With functions and types, it's easy, but how about the variables initialized at the point of definitions, and constants? The "trick" is: there are declarations and definitions (for functions, too, but we are talking about variables and constants). When a variable or constant is initialized, it has to be a definition; it defines really existing object. This should be done only once in a compilation unit. Think by yourself: if, by the effect of all you "includes", you have two different declaration, should it compile? For example:
C++
// won't compile:
const char * lp = "abc";
const char * lp = "cde";

Of course, not. How a compiler would "know" what value do you really need "abc" or "cde"? (Note: this is not assignment; this is initialization!) If you understand that, what's the difference if you initialize with the same value. This won't compile, too:
C++
// won't compile:
const char * lp = "abc";
const char * lp = "abc";

The real reason is: you cannot have two really existing objects with the same name, because the compiler would not "know" which one to link when you mention the name anywhere in code.

In contrast to this situation, you can have one or more declarations of the same object using the word extern:
http://msdn.microsoft.com/en-us/library/0603949d.aspx[^].

Note that it does not mean that the definition should be in a separate compilation unit. It only say that it has the static duration. If the compiler cannot find the static definition in the scope of the current C++ file (same compilation unit), it creates a reference by name in the object file, and then the linker will try to find the definition in other object files.

—SA
 
Share this answer
 
Comments
jiazhiqiang 17-Oct-14 1:22am    
I totally understand what you are saying.
I really put "const char * lp = 'abc'" in a header and then included by different cpp files,leading same variable is defined in different compiler-unit.

But I just don't understand why "const int n = 1 " is OK ? any hint ?
Sergey Alexandrovich Kryukov 17-Oct-14 10:58am    
It's not OK. Same thing. Maybe you just did not include it twice. This line, to, should not appear in a header file. All static variables/constants in header files should go as "extern". Please see my comments to Solution 3 (which is wrong).
A hint? Yes. Don't use black-box thinking (recipes, trial-response), use open-box analysis.
—SA
nv3 17-Oct-14 11:36am    
OP is saying that his compiler accepts a multiple definition of "const int n = 1". I am apt to believe him, because as far as I remember the compiler is allowed to accept that as long as the value is the same in all definitions. And that makes sense, because most compilers not even reserve memory for such a const variable, but just insert the value as a literal in all occurrences. And that would explain why he doesn't get an error message in that case.

In the example of "const char* pl = "abc" the compiler is forced to make a memory allocation for the string, because all strings are writable in C and C++. And hence the compiler has no other option than to complain about not being able to instantiate two pointer variables with the same name and different contents.
Sergey Alexandrovich Kryukov 17-Oct-14 11:57am    
This is nothing but incorrect observation. Write this line twice and observe the error message "redefinition".
You can try it to see it.
This is what it is. OP probably had only one line into compilation, in this case, more than one in another cases.
—SA
Aescleal 21-Oct-14 7:13am    
It's not the compiler that's complaining - it's the linker. The OP is comparing the behaviour of a constant with a mutable pointer to a constant.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900