Solved

externs (possibly silly question)

Posted on 2001-07-27
37
226 Views
Last Modified: 2010-08-05
If I have a variable "const int blah", how do I declair an extern for it.  If I use "extern const int blah" or "extern int blah" I get link errors.  No proboem if I have "int blah" and "extern int blah".  I am using visual C++.

Thanks,

Doug
0
Comment
Question by:dayers
  • 12
  • 8
  • 6
  • +2
37 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
The idea on using 'extern' is to only use it when needed, e.g.

#ifndef __MAIN_MOD // no 'extern' needed in the module that declares it
extern
#endif
const int blah;

So, in your main module (the one that exports 'blah'), define __MAIN_MOD and the compiler will see the above as

const int blah;

In the module that imports it (and __MAIN_MOD is not defined), the compiler will see it as

extern
const int blah;
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
The standard says:

A name having namespace scope (3.3.5) has internal linkage if it is the name of:
[...]
? an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; [snip]

So declare both as extern const.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
AssfLavie, are you sure you posted that in the right question?
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Why do you ask?
The OP asked why he got a link error when trying to define an extern for a const integer in another translation unit. The std says that consts have default internal linkage and so the caller has to declare the const as extern in both translation units.
Do you fail to see the relevance of this answer to the OP's question?
0
 

Author Comment

by:dayers
Comment Utility
Sorry I don't quite understand the answer.  I am doing the following and getting a link error:

in file "blah.h":

#ifdef MOD_BLAH

const int blah = 7;

#else

extern const int blah;

#endif

I have also tried the following with the same result:

in file "blah.h":

#ifdef MOD_BLAH

const int blah = 7;

#else

extern int blah;

#endif

How should I chagne the code so I don't get a link error?

Thanks for the comments,

Doug
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>Why do you ask?
The questioner said he tried "const int blah" and "extern const int blah" combination.
And he saying he still got an error.

May I suggest that you post your answers as comments.  Using this method, you can avoid possibly posting incorrect answers.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Hi (dayers):
Feel free to click the [Reject Answer] button near (Answer-poster's) response, even if it seems like a good answer.
Doing so will increase your chance of obtaining additional input from other experts.  Later, you can click the [Select Comment as Answer] button on any response.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
The following is the correct method:
in file "blah.h":
#ifdef MOD_BLAH
const int blah = 7;
#else
extern const int blah;
#endif

You could have something wrong somewere else.
Could you please compile this method, and post the exact error code.

Can you post the code that the error reffers too.
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Maybe you misundestood my answer, Axter. I suggested defining both as extern. Try it.
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Maybe you misundestood my answer, Axter. I suggested defining both as extern. Try it.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
It also would help if you posted "blah.cpp" or "blah.c"

At least the top part where it does the include for "blah.h"

In your cpp file it should look like this:

#define MOD_BLAH
#include "blah.h"

The blah.c file should be the only file that defines MOD_BLAH
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>Maybe you misundestood my answer, Axter. I suggested
>>defining both as extern. Try it.
You're right, I did misundestood your answer.
Sorry.
0
 

Author Comment

by:dayers
Comment Utility
blah.cpp is the only file that defines MOD_BLAH.  

How could it work if you only had externs?  You need to define a variable at some point right?  There is really nothing else relavent in blah.cpp...  what do you think you need to know?

Doug
0
 

Author Comment

by:dayers
Comment Utility
blah.cpp is the only file that defines MOD_BLAH.  

How could it work if you only had externs?  You need to define a variable at some point right?  There is really nothing else relavent in blah.cpp...  what do you think you need to know?

Doug
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>How should I chagne the code so I don't get a link error?

Both has to be 'const int', regardless of 'extern' or not. Where do you #define MOD_BLAH? The best idea would be

// mod_blah.cpp
#define MOD_BLAH
#include "blah.h"

// blah.h
#ifndef MOD_BLAH
extern
#endif
const int blah;

// mod_other.cpp
#include "blah.h"
0
 
LVL 4

Accepted Solution

by:
AssafLavie earned 50 total points
Comment Utility
If I understand the situation correctly, the OP has at least one translation unit in which he defines a const integer (which should be initialized, btw) and another translation unit in which he wishes to define an extern for the const.
Both declaration should have extern or else there would be unresolved external symbols.
Example:
If for instance one file has:
const int a = 1;

and another file has:
extern const int a;

The linker would yell that it cannot find the definition of 'a' because it wasn't declared extern (and global consts have internal linkage by default).

The right declaration should be
extern const int a = 1;
and
extern const int a;

In any case, Axter, I don't apreciate you telling the OP what to do with my answer. If you disagree, post your comment and let the OP decide. Don't tell him, or me, how to behave and what to do. Even if I am mistaken (which I'm fairly sure I'm not) I still have a right to post my response as an answer if I'm sure of myself.
The one thing EE doesn't need is rude moderators such as yourself.
0
 

Author Comment

by:dayers
Comment Utility
blah.cpp is the only file that defines MOD_BLAH.  

How could it work if you only had externs?  You need to define a variable at some point right?  There is really nothing else relavent in blah.cpp...  what do you think you need to know?

Doug
0
 

Author Comment

by:dayers
Comment Utility
blah.cpp is the only file that defines MOD_BLAH.  

How could it work if you only had externs?  You need to define a variable at some point right?  There is really nothing else relavent in blah.cpp...  what do you think you need to know?

Doug
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
The fact that both would have 'extern' doesn't mean that there is no definition.
The following is a full definition of a constant variable with external linkage:
extern const int a = 0;

If you compile only this, you will have no link errors.

If you try to define another extern for this variable in another file (which is the only reason to mess around with the extern keyword anyway), you should declare it as:
extern const int a; // With no initialization.

Both declaration will point to the same const variable.
0
 

Author Comment

by:dayers
Comment Utility
Thanks for the help.  That worked great!
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
FYI,
In VC++ I was able to compile a project using the following method:

#ifdef MOD_BLAH
const char *blah_str = "test";
const int blah = 7;
const int &blapRef = blah;
#else
extern const char *blah_str;
extern const int &blapRef;
#endif

It seems for some reason the code will not compile an integer using the "const int blah" and "extern const int blah" combination.  I don't understand AssafLavie reason for this.

This is not the case with other variable types, as you can see from the above example.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
I've been trying to post this for about an hour, but there's been some problem.  I'm not sure it if it with EE or on my end here.  But anyways.

******************************************************

C++ has a multi declaration, one definiton rule.  This states that things can be declared multiple times, but must be defined exactly one time.  i.e. it is an error (usually) to not define something and it is an error (always) to define it multiple times.   However, things may be declared any number of times.

Unfortunately, its not quite that simple.  You must also consider linkage.  

If an object or function has external linkage, then the compiler exports that object or function from the translation unit in which it is defined.  (A translation unit is a single "file" actually submitted to the compiler, it is produced from one of your source code files (a.cpp file, for example) and all the include files that it includes.)  This means that the definition for this object or function can be shared between all the translation units in the project.      

If an object object or function has internal linkage, then the compiler does not export the object or function from the translation unit.  This means that the object or function is hidden within the translation unit and cannot be "seen" by other translation units.

So to satisfy the one defintion rule for an object or function you need to consider its linkage.  If the object or function is to be shared between multiple translation units, then each translation unit needs to have a declaration for the object/function that declares the object/function with external linkage.  In addition, one and only one translation unit needs to define the object or function.    If the object or function is to be used within only one translation unit, then there may be multiple declarations for the object/function within that translation unit and there must be one definition for that object/function within the translation unit.  It is best if the declarations for the object or function declare it with internal linkage so that the object or function does not get shared with other translation units by mistake.

so to share an int between translation units you need to place external declarations in every tranlsation unit that needs the int.  Like

extern int i;

This can be placed in an include file, so that it can be included in any translation unit that needs it.

but you also must define a single instance of this integer with external linkage.  thus one translation unit must have a definition like

int i;

This single definition should not usually be placed in an include file.  This is because the include file could be included into multiple translation units and then multiple translation units would then define the int, thus violating the one definition rule.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> t seems for some reason the code will not compile an integer using the "const int blah"
const int blah

defines--not declare--an int with internal linakge, not external, and no initialization.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> The one thing EE doesn't need is rude moderators such as yourself.
Axter is not a moderator.
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Yes, nietod. But if you're talking about global consts (not just plain global ints) then you have to use extern even for the definition. This is because consts have internal linkage.

I really don't understand what all the confustion is about (and I also don't understand the status of this question. Correctly, I see it in my browser and Ansewerd (green) and laso rejected (red)).
Given this situation:

a.cpp
====
const int a = 1;

b.cpp
====
extern const int a;

The linker will complain about an unresolved external symbol 'int const a'.

Given the situation:

a.cpp
=====
extern const int a = 1;

b.cpp
=====
extern const int a;

Everything should compile and link fine.



0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Yes, nietod. But if you're talking about global consts (not just plain global ints) then you have to use extern even for the definition. This is because consts have internal linkage.

I really don't understand what all the confustion is about (and I also don't understand the status of this question. Correctly, I see it in my browser and Ansewerd (green) and laso rejected (red)).
Given this situation:

a.cpp
====
const int a = 1;

b.cpp
====
extern const int a;

The linker will complain about an unresolved external symbol 'int const a'.

Given the situation:

a.cpp
=====
extern const int a = 1;

b.cpp
=====
extern const int a;

Everything should compile and link fine.



0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
I know. But he acts like one. A rude one.
0
 

Author Comment

by:dayers
Comment Utility
I rejected the original answer, but your later post cleared it up for me so I accepted it as the answer.  I think that is the reason for the strangeness.

Thanks for the help!

Doug
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> Yes, nietod.
???  I'm not saying anything that dissagrees with you or with that.    In fact none of what you posted was visible when i wrote my poste--otherwise I probalby wouldn't have.   Constants of any type--not just int--default ti internal linkage.  This is an effort to make constants ase useful as the C pre-processor macros they were intended to largely replace.  

>> I really don't understand what all the confustion is about
I'm not confused  Who is confussed?

>>  I see it in my browser and Ansewerd (green) and laso rejected (red)).
>> Given this situation:
Your first answer was rejected and should therefore show as red.  Then either a different answer was accepted or a comment of yours was accepted as an answer.   This is not an EE bug or anytning.  I don't get to say that often.

>> I know. But he acts like one. A rude one.
If you have a complaint about an expert, its best to take it to customer service so they can do something about.  Try to avoid flame wars if possible.
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
Sorry, I'm not the type that will compain to the teacher.

In any case, notice how my original short answer was correct and provided a full explanation.
The OP got confused by some people in this forum, but my more recent comment added nothing to the original answer.
If he had only tried out my suggestion the question would have been closed a long time ago.

I'm not the one who's making a big deal here or starting a flame war. Axter and jkr were the ones that chose to confront me and my answer publically, instead of trying to provide an answer of their own.

Also, to the OP: You shouldn't reject an answer if you don't understand it. Nothing is stopping you from requesting further explanation, but to reject an answer is to say it is wrong. Read my first post carefully and you will see that my last comments just re-iterated what has already been written in the std and quoted in my answer.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>Axter and jkr were the ones that
>>chose to confront me and my answer publically, instead
>>of trying to provide an answer of their own.

I cannot see that I did confront you, and I definitely DID try to provide an answer. What I don't understand is the fuzz that you're making. Axter knows that e.g. both nietod and I don't like his way to suggest users to reject answers. But I don't want YOU to complain about that:

http://www.experts-exchange.com/jsp/qShow.jsp?ta=winprog&qid=20147837

Conforming to your behaviour in THAT thread, the first comment here would have qualified...
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
jkr: You didn't try to provide an answer in your first comment. Your first comment was all about me. Telling me that I seem to be blathering off topic jibrish when I actually posted a complete answer to the OPs question.

And what does anything that happened in this thread has to do with the PAQ you mentioned??

Regarding that thread: I really didn't follow up on your comments regarding my choice of answer, but when I did see them now I think your reactions were silly. I didn't really need the solution, so I couldn't have chosen the solution I would have used, since I wasn't going to use it.
I didn't even bother to check if the solutions worked. I posted the question because I was curious. That's it. Once I got an answer I gave the points automatically, which is my right to do. I also mentioned that I liked the other solution better (was meant as a compliment). I guess I'll know from now on who to compliment and who to avoid.

Regardless, Axter's behaviour here was rude. At least in my opinion. Now you can agree with that or not but don't come at me for bringing that up. Axter tried to convince the OP to dump my answer and all I did was object to that in my comments. That's my right.
I'm sorry you feel you have justify his actions in this thread by coming at me and trying to show me were I've done similar things in the past. That's juvenile. Not to mention that the PAQ you mentioned here is a totally different case...

jkr, what if you had answered someone's question and another expert who probably didn't udnerstand the answer came along and suggested that the OP reject your answer?What if another guy came along and hinted publically that you're answer is so out of touch with reality that it seems that it's posted by accident on the wrong thread?
How would you feel?
What if when you tried to object to that you were told you were a hipocrit?

nietod suggested that I avoid flame wars. I generally agree. That's why you don't see me arguing in MS/SUN C++/C# discussions. However, when someone is coming at me on a perosnal level I will always go through the trouble of justifying myself. Even at the cost of the resemblance to a flame war.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> jkr: You didn't try to provide an answer in your first comment. Your first comment
>> was all about me. Telling me that I seem to be blathering off topic jibrish when I
>> actually posted a complete answer to the OPs question.
It looks to me like jkr's complaint was that what you posted seemed to be irrelvenat or at least not helpful to the questioner.  While it was correct and quite relevant to some one who knows the material, to someone who doesn't yet understand it, its basically incomprehensible.   (The only way to understand the C++ standard is to know how to program in C++.  :-)   It doesn't even begin to tell them what to do to solve the problem.  Compare it to your finally accepted answer is far more useful.  I suspect that is what jkr was arguiing with and I certainly woudl have to agree with himn on that--and even if that is not what he was saying.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>jkr: You didn't try to provide an answer in your first
>>comment. Your first comment was all about me.

My first comment was the very first on this thread - what are you talking about?

>>Telling me that I seem to be blathering off topic
>>jibrish when I

My post was "AssfLavie, are you sure you posted that in the right question?". I cannot see that this is disrespectful.  That happened to others nefore, and it happened to me. To qoute:

Q: "...I get link errors"
A: "A name having namespace scope (3.3.5) has internal linkage if it is the name of:"

I don't mind people posting answers, but if you do so, expect criticism if they seem unclear.

>>Once I got an answer I gave the points automatically,
>>which is my right to do

You can give your points to anyone you want, I can give assistance to anyone I want. Fair enough. I'll keep that in mind.

>>jkr, what if you had answered someone's question and
>>another expert who probably didn't udnerstand the
>>answer came along and suggested that the OP reject your
>>answer?

I didn't do that. It was you who posted

>>Axter and jkr were the ones that
>>chose to confront me and my answer publically, instead
>>of trying to provide an answer of their own.
0
 
LVL 4

Expert Comment

by:AssafLavie
Comment Utility
nietod:
I agree. The std isn't the most friendly and easy to read document. Perhaps I should have added an explanation of my own apart from handing the solution to the problem. However, I really don't like the fact that people automatically get treated like they know very little and have to have everything explained to them like novices. Even if they are, give them the benefit of the doubt.
If the OP finds my answer unlcear - fine, I'll explain in furthere detail. But I resent the fact that others feel like they have to step in and act like moderators. Especially experienced experts who probably know exactly what my intent was and what my obscure answer was all about.

I think that getting the dry version of the answer at first is prefered and lengthy explanations should be given only if requested. I don't like it when people bother explaining really simple stuff to me (stuff that I already know) just because they don't want to take the chance that I'll dont understand. Give me/others the benefit of the doubt. If I don't understand I'll ask again - that's what the whole idea is about. (It's called an ego, we all have one)
People ask their questions here in a public manner and they deserve to be treated like professionals. I don't like jumping on people and offerig to teach them stuff that they might already know (just so Im SURE i'll get my points). I prefer to assume that the fact that they have a difficulty and have to ask a question doesn't mean they are completely new to the subject.
For exmaple, if someone gets a link error like the one in this thread, I assume that they do know about linkage and that they only missed the fact that global consts have default internal linkage (as opposed to non-consts). If I later see that a more comprehensive explanation is in order - I give it. But I wouldn't offer it right from the top.
I hope you catch my drift.

I any case, you're right about quoting from the std in EE. I'll keep that in mind.
0
 

Author Comment

by:dayers
Comment Utility
AssafLavie you are right, your first answer was sufficient.  I should have tried it out before rejecting it.  I guess I did not understand the reasoning.  It all makes since now.  

Hope there are no bad feelings.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> However, I really don't like the fact that people automatically get treated
>> like they know very little and have to have everything explained to
>> them like novices.
This is a very basic issue so its very unlikey that the client has much experience with linkage or the C++ standard.  If they were asking about specializing templates, you could probably assume a more advanced knowledge of C++.  Its not insulting to the client to assume they don't know much on the topic, since they are asking a question about the topic.

>>If the OP finds my answer unlcear - fine, I'll explain in furthere detail.
>> But I resent the fact that others feel like they have to step in and
>> act like moderators
My feeling is that if your question is right (the first right one too) then it should qualify for the answer.  If the client doesn't understand it, then you should at least be given the opportunity to explain it better detail.   This happens a lot even when the answer is actually clear and written for the level of the client.   I think jkr agrees with this.   I know Axter doesn't.  Axter will suggest that the answer be rejected even if it is 100% clear and correct.   jkr does not do this.  jkr wasn't even suggesting that it be rejected.  He was questioning whethor or not it was actually correct or relevant because ti was so vague.

>>  I don't like it when people bother explaining really simple stuff to me
But I bet you don't ask simple questions.   usually the question gives you a good idea of the appropriate level of the answer.  If you have to err, err on the side of safety and provide more information.  There is no harm in that, then the client doesn't have to wait for you to get back to them.

>>  don't like jumping on people
Teaching isn't "jumping on people".  By asking the question they've made it clear that then don't know the material well enough.  Obviously you have to tell them something new, there's no harm when some of that overlaps with something old.  

>> I assume that they do know about linkage and that they only missed
>> the fact that global consts have default internal linkage
Many many advanced programmers--professionals--don't understand linkage.  They've learned a couple of methods that work for them along the way, but when they have to depart from those rules they are in trouble.  This is especially tru in C++ since its rules about linkage are so--well a mess.  Its got to be the only language where some things, but not all things, default to external linkage.  In most langauges everything defaults to internal linkage.  That makes much more sense.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now