473,671 Members | 2,255 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

rules of extern

I have a few global variables in my app. They are defined in the main
application class file and declared (extern) in a header which can be
included by anyone who would want to use these variables.

Two of the globals are pointers which are initialized at runtime. The others
are classes whose values are initialized in the global space. When I had
just the pointers, I didn't need to include the extern header in the
defining class file. But now that I have the objects, I do. If I don't, ld
complains about undefined references.

Why is this?

It looks basically like this:

main.cpp

A *ptr;
B obj("string literal");

secondary.cpp

#include "externs.h"

void Secondary::meth od() {
cout << obj.toCharArr() ;
}

externs.h

class A;
class B;

extern A *ptr;
extern B obj;

Thanks,

--John Ratliff
Jul 26 '05 #1
4 2589

"John Ratliff" <so*****@micros oft.com> wrote in message
news:SKrFe.1810 20$x96.174068@a ttbi_s72...
I have a few global variables in my app. They are defined in the main
application class file and declared (extern) in a header which can be
included by anyone who would want to use these variables.

Two of the globals are pointers which are initialized at runtime. The
others are classes whose values are initialized in the global space. When
I had just the pointers, I didn't need to include the extern header in the
defining class file.
I don't understand. What's "the defining class file"?
But now that I have the objects, I do. If I don't, ld complains about
undefined references.

Why is this?

Any unit which references a variable must be able to "see" that variable
somehow. Below, secondary.cpp contains code which references obj, so obj
must be defined somewhere visible to secondary.cpp, which is what including
externs.h does for it. This minimal example doesn't show ptr being used
anywhere, so naturally it won't require externs.h. Perhaps your real code
does have ptr referenced there somewhere, but if it does, it has to define
ptr _someplace_ which is visible to the code. But without the real code,
I'd only be guessing.
It looks basically like this:

main.cpp

A *ptr;
B obj("string literal");

secondary.cpp

#include "externs.h"

void Secondary::meth od() {
cout << obj.toCharArr() ;
}

externs.h

class A;
class B;

extern A *ptr;
extern B obj;

Thanks,

--John Ratliff

Jul 26 '05 #2
Yeah, sorry for the not real code, but I can't seem to reduce the real code
to a small compilable problem. Let me try and rephrase.

In the file where the storage space for these globals is created, if I don't
also have the extern declarations, the linker will say my globals (the ones
that are not pointers) will say there are undefined references to these
variables. In other words, unless I have an extern declaration of these
variables (the ones that are not pointers), the linker will not export them
to the other modules. Yet, it exports the pointers with or without including
the extern declarations.

Is it a C++ requirement that I use an extern declaration if I want to export
these symbols? Are they limited to the module if I don't?

I guess maybe a better question might be, are variables declared at file
scope exported or not? Does the export require an extern declaration?

I read this in the C++ Faq Lite " (By the way, static data at file-scope is
now deprecated in C++: don't do that.) ". What does this mean? Is it saying
what I did was bad?

BidEuchreApp.cc (where storage space is defined for the globals)
------------------
#include "AppConstants.h h"

wxMutex *mutex;
wxCondition *cond;

const wxString APP_NAME(wxT(PA CKAGE_NAME));
const wxString APP_VERSION(wxT (PACKAGE_VERSIO N));
const wxString APP_COPYRIGHT(w xT("Copyright (C) 2005 John David Ratliff"));
const wxString APP_URL(wxT("ht tp://games.technopla za.net/"));

BidEuchreApp::B idEuchreApp() {
mutex = new wxMutex();
cond = new wxCondition(*mu tex);
}
------------------

AppConstants.hh
-------------------
class wxCondition;
class wxMutex;
class wxString;

extern const wxString APP_NAME;
extern const wxString APP_VERSION;
extern const wxString APP_COPYRIGHT;
extern const wxString APP_URL;
extern wxCondition *cond;
extern wxMutex *mutex;
---------------------------------

EuchreFrame.cc
-----------------------
#include "AppConstants.h h"

void EuchreFrame::he lpAbout(wxComma ndEvent& WXUNUSED(event) ) {
wxString message = APP_NAME + wxT(' ') + APP_VERSION + wxT('\n') +
APP_COPYRIGHT + wxT('\n') + APP_URL;
wxString title = wxT("About ") + APP_NAME + wxT("...");

wxMessageBox(me ssage, title, wxOK | wxICON_INFORMAT ION, this);
}
----------------------

Here is the actual code. I will post the entire compilable module if you
think it will help, but I have 30 some files and it requires wxWidgets 2.6
to compile. You can assume it does use cond and mutex somewhere, but not in
EuchreFrame.cc or BidEuchreApp.cc .

If you remove the include of AppConstants.hh in the BidEuchreApp.cc file,
you will get the following linker errors.

ui/EuchreFrame.o(. text+0x1266):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_VERSION'
ui/EuchreFrame.o(. text+0x12b8):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_COPYRIGHT'
ui/EuchreFrame.o(. text+0x130d):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_URL'
ui/EuchreFrame.o(. text+0x13b5):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 78:
undefined reference to `APP_NAME'
collect2: ld returned 1 exit status

The question is, why does the linker find the cond and mutex variables, but
not the APP_XXX variables?

Game.cc
----------------------
void Game::setPause( bool paused) {
this->paused = paused;
cond->Signal();
}
----------------------

Just one of the places cond is used, and ld has no problem with
BidEuchreApp.hh not including AppConstants.hh .

Thanks,

--John Ratliff
Jul 26 '05 #3

"John Ratliff" <so*****@micros oft.com> wrote in message
news:CjzFe.1837 68$_o.148646@at tbi_s71...
Yeah, sorry for the not real code, but I can't seem to reduce the real
code to a small compilable problem. Let me try and rephrase.

In the file where the storage space for these globals is created, if I
don't also have the extern declarations, the linker will say my globals
(the ones that are not pointers) will say there are undefined references
to these variables. In other words, unless I have an extern declaration of
these variables (the ones that are not pointers), the linker will not
export them to the other modules. Yet, it exports the pointers with or
without including the extern declarations.

Is it a C++ requirement that I use an extern declaration if I want to
export these symbols? Are they limited to the module if I don't?

The extern specifier tells the compiler that the symbol is defined
elsewhere, and the reference must be resolved at link time.
I guess maybe a better question might be, are variables declared at file
scope exported or not? Does the export require an extern declaration?

You don't "export" the symbol. You simply declare it as exterrn in any unit
that needs to see it but doesn't wish to directly include the file it's
declared in. In your case, you declare it extern in a header, and include
the header wherever it's needed. That's the correct way.
I read this in the C++ Faq Lite " (By the way, static data at file-scope
is now deprecated in C++: don't do that.) ". What does this mean? Is it
saying what I did was bad?

I see nothing declared as "static" here.
BidEuchreApp.cc (where storage space is defined for the globals)
------------------
#include "AppConstants.h h"

wxMutex *mutex;
wxCondition *cond;

const wxString APP_NAME(wxT(PA CKAGE_NAME));
const wxString APP_VERSION(wxT (PACKAGE_VERSIO N));
const wxString APP_COPYRIGHT(w xT("Copyright (C) 2005 John David
Ratliff"));
const wxString APP_URL(wxT("ht tp://games.technopla za.net/"));

Those are your declarations (and definitions of the wxString variables).
BidEuchreApp::B idEuchreApp() {
mutex = new wxMutex();
cond = new wxCondition(*mu tex);
}
Fine, because cond and mutex are declared above.
------------------

AppConstants.hh
-------------------
class wxCondition;
class wxMutex;
class wxString;

extern const wxString APP_NAME;
extern const wxString APP_VERSION;
extern const wxString APP_COPYRIGHT;
extern const wxString APP_URL;
extern wxCondition *cond;
extern wxMutex *mutex;
---------------------------------

EuchreFrame.cc
-----------------------
#include "AppConstants.h h"

void EuchreFrame::he lpAbout(wxComma ndEvent& WXUNUSED(event) ) {
wxString message = APP_NAME + wxT(' ') + APP_VERSION + wxT('\n') +
APP_COPYRIGHT + wxT('\n') + APP_URL;
wxString title = wxT("About ") + APP_NAME + wxT("...");

wxMessageBox(me ssage, title, wxOK | wxICON_INFORMAT ION, this);
}
----------------------

Here is the actual code. I will post the entire compilable module if you
think it will help, but I have 30 some files and it requires wxWidgets 2.6
to compile. You can assume it does use cond and mutex somewhere, but not
in EuchreFrame.cc or BidEuchreApp.cc .

If you remove the include of AppConstants.hh in the BidEuchreApp.cc file,
you will get the following linker errors.

I must assume that you mean the problem occurs if you remove the include
from EuchreFrame.cc, since that's what the errors refer to. And
EuchreFrame.cc needs to tell the compiler where those symbols are defined.
It does so (in this case) by including the header file which declares them
as extern (thereby putting it on the linker to resolve the extern
declarations).
ui/EuchreFrame.o(. text+0x1266):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_VERSION'
ui/EuchreFrame.o(. text+0x12b8):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_COPYRIGHT'
ui/EuchreFrame.o(. text+0x130d):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_URL'
ui/EuchreFrame.o(. text+0x13b5):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 78:
undefined reference to `APP_NAME'
collect2: ld returned 1 exit status

The question is, why does the linker find the cond and mutex variables,
but not the APP_XXX variables?
It doesn't. Look again. The pointers are never referenced in
EuchreFrame.cc, which is where the errors occur.

Game.cc
----------------------
void Game::setPause( bool paused) {
this->paused = paused;
cond->Signal();
}
----------------------

Just one of the places cond is used, and ld has no problem with
BidEuchreApp.hh not including AppConstants.hh .


You don't show what's included by Game.cc (or what's included by what it
includes...). So I can't tell where it's seeing cond from, but trust me,
it's included somehow.

You don't show any code from BidEuchreApp.hh , so I can't comment on that
one. My guess is that neither mutex nor cond are referenced in that file.
They are referenced in BidEuchreApp.cc , but that's where they are declared,
so there's no problem there.

I think you're just confusing EuchreFrame.cc and BidEuchreApp.cc here. It
doesn't matter if the variable is a pointer or any otther kind of object..it
must either be declared in the file, declared in an included file (or a file
included by a file that's included, etc.), or declared as extern (and then
actually defined elsewhere).

-Howard
Jul 27 '05 #4
>>If you remove the include of AppConstants.hh in the BidEuchreApp.cc file,
you will get the following linker errors.
I must assume that you mean the problem occurs if you remove the include
from EuchreFrame.cc, since that's what the errors refer to. And
EuchreFrame.cc needs to tell the compiler where those symbols are defined.
It does so (in this case) by including the header file which declares them
as extern (thereby putting it on the linker to resolve the extern
declarations).


No, this is not what I mean. I am really and truly referring to
BidEuchreApp.cc . It does not make sense to me either. EuchreFrame.cc has
AppConstants.hh included at the top, before it uses the globals. If it
did not, wouldn't I get a compiler error and be unable to reach the link
stage?

This doesn't seem right, but is it possible the rules are different for
global objects than global pointers (or other primitives)? Is it
possible objects are static by default, and primitives are extern?

ui/EuchreFrame.o(. text+0x1266):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_VERSION'
ui/EuchreFrame.o(. text+0x12b8):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_COPYRIGHT'
ui/EuchreFrame.o(. text+0x130d):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 77:
undefined reference to `APP_URL'
ui/EuchreFrame.o(. text+0x13b5):C:/msys/1.0/home/jdratlif/bideuchre/source/ui/EuchreFrame.cc: 78:
undefined reference to `APP_NAME'
collect2: ld returned 1 exit status

The question is, why does the linker find the cond and mutex variables,
but not the APP_XXX variables?

It doesn't. Look again. The pointers are never referenced in
EuchreFrame.cc, which is where the errors occur.


Yes it does. They are used in Game.cc, and Game.cc produces no errors. I
can even remove the use of the APP_XX constants from EuchreFrame and the
include from BidEuchreApp.cc and Game.cc will still be able to use the
cond and mutex.
Game.cc
----------------------
void Game::setPause( bool paused) {
this->paused = paused;
cond->Signal();
}
----------------------

Just one of the places cond is used, and ld has no problem with
BidEuchreApp. hh not including AppConstants.hh .
You don't show what's included by Game.cc (or what's included by what it
includes...). So I can't tell where it's seeing cond from, but trust me,
it's included somehow.


Game.cc includes AppConstants.hh . Sorry.

You don't show any code from BidEuchreApp.hh , so I can't comment on that
one. My guess is that neither mutex nor cond are referenced in that file.
They are referenced in BidEuchreApp.cc , but that's where they are declared,
so there's no problem there.
I meant BidEuchreApp.cc here. Apologies again. BidEuchreApp.hh is solely
a class def with no includes whatsoever.

I think you're just confusing EuchreFrame.cc and BidEuchreApp.cc here. It
doesn't matter if the variable is a pointer or any otther kind of object..it
must either be declared in the file, declared in an included file (or a file
included by a file that's included, etc.), or declared as extern (and then
actually defined elsewhere).


Thanks for all your time. I hope we're closer to solving this. Actually,
I don't care that I have to include the file in BidEuchreApp.cc where
they are defined. I just want to know why I do.

--John Ratliff
P.S. I don't know if it's helpful, but I posted the entire source at
http://www.technoplaza.net/temp/bideuchre-0.1.tar.bz2. Unless you have
wx 2.6, you won't be able to compile it though.
Jul 27 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
6174
by: Mark A. Gibbs | last post by:
I have a question about mixing C and C++. In a C++ translation unit, I want to define a function with internal linkage and C calling convention. Here's a sample of what I want to do: // main.cpp // This is defined in a C module extern "C" void fake_qsort(void*, std::size_t, std::size_t, int (*compare)(const void*, const void*));
11
3466
by: Bradford Chamberlain | last post by:
I work a lot with multidimensional arrays of dynamic size in C, implementing them using a single-dimensional C array and the appropriate multipliers and offsets to index into it appropriately. I tend to iterate over subsets of these arrays by walking a pointer and an offset per dimension across their dimensions. I've found that this tends to result in more performance in a portable manner than doing explicit indexing calculations and...
19
3845
by: ccwork | last post by:
Hi all, I am reading "C: A Reference Manual" 4th ed and I get lost for the "extern". It says that global object without specifying the storage-class specifier will have "extern" as the default storage-class specifier. My (little) C experience tells me that an object with "extern" is to let the linker knows that the object is referencing the object defined in somewhere, and this "somewhere" object does not have the storage-class specifier...
5
16601
by: siliconwafer | last post by:
Hi all, I wanted to know that is use of extern keyword mandatory in case of global variables and functions used in other source files? i.e consider a following piece of code from MSDN explaining extern storage class: /****************************************************************** SOURCE FILE ONE *******************************************************************/ extern int i; /* Reference to i, defined below */
17
4921
by: Tapeesh | last post by:
I would like to know what is the expected behaviour of C compilers when an extern decleration is intialized. When the following code is compiled using gcc //File extern.c int arr ; int a ;
3
4132
by: fctk | last post by:
are the following rules correct in C89/C90? ---- SCOPE RULES 1) the scope of an identifier declared inside a block is the block in which it is declared; 2) when you have nested blocks (extern block and internal block), an identifier declared in the external block is known also in the internal block, while an identifier declared in the internal block is not known
13
2089
by: fctk | last post by:
source: http://rm-f.net/~orange/devel/specifications/c89-draft.html#3.1.2.2 there are two passages in this paragraph i can't fully understand: 1) "If the declaration of an identifier for an object or a function contains the storage-class specifier extern , the identifier has the same linkage as any visible declaration of the identifier with file scope. If there is no visible declaration with file scope, the identifier has external...
5
2852
by: Christian Christmann | last post by:
Hi, I've tree questions on the storage class specifier "extern": 1) Code example: int main( void ) { int b = -2; // my line 3 if ( a ) {
4
6253
by: mimi | last post by:
The programmer indicates to the compiler that a function is written in a different programming language using a linkage directives.It is intuitive that extern "SomeLanguage" is used to declare functions written in the "SomeLanguage". But I am quite confused what information does the linkage directive tells the compiler.The "generated" function name? The way the arguments are ordered?Or something else? And I am still wondering why extern...
0
8476
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8393
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8914
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8670
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7433
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6223
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5695
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
2810
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2051
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.