473,386 Members | 1,821 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

why static variables used in EXE and DLL are different?

In a static library, there is a static variable definition.

static CLogger::mapFile;

In both EXE and DLL, I use the same code. CLogReader uses
CLogger::mapFile to do some work.
CLogReader logReader;

But the result is different.

When used in EXE, mapFile constructor is not called? (Why?). See EXE
log below.

Creating map file 0x00499f90 (call CMapFile constructor)
Enter CLogReader now ...
GetMapFile 0x00499f90 ... (return the static mapFile)
Exit CLogReader now ...

When used in DLL, mapFile constructor is called, but after the first
use. See DLL log below

Enter CLogReader ...
GetMapFile 0x10025830 ... (return the static mapFile)
Exit CLogReader ...
Creating map file 0x10025830 (in CMapFile constructor)

It is too strange to understand. Why???

Dec 12 '06 #1
9 8318
Allen wrote:
In a static library, there is a static variable definition.

static CLogger::mapFile;

In both EXE and DLL, I use the same code. CLogReader uses
CLogger::mapFile to do some work.
Off topic here, try a windows programming group.

--
Ian Collins.
Dec 12 '06 #2
Allen wrote:
In a static library, there is a static variable definition.
....
It is too strange to understand. Why???
Do you have a small code sample that exhibits this behaviour ?
Dec 12 '06 #3

Allen schrieb:
In a static library, there is a static variable definition.

static CLogger::mapFile;

In both EXE and DLL, I use the same code. CLogReader uses
CLogger::mapFile to do some work.
CLogReader logReader;

But the result is different.

When used in EXE, mapFile constructor is not called? (Why?). See EXE
log below.

Creating map file 0x00499f90 (call CMapFile constructor)
Enter CLogReader now ...
GetMapFile 0x00499f90 ... (return the static mapFile)
Exit CLogReader now ...

When used in DLL, mapFile constructor is called, but after the first
use. See DLL log below

Enter CLogReader ...
GetMapFile 0x10025830 ... (return the static mapFile)
Exit CLogReader ...
Creating map file 0x10025830 (in CMapFile constructor)

It is too strange to understand. Why???
Well, the following is a wild guess only, try to follow the guidelines
for posting on this newsgroup for better answers next time, (esp.
http://www.parashift.com/c++-faq-lit...t.html#faq-5.8)

It seems you have used two static variables of type CLogReader and
CMapFile and rely on the order of their initialization (you probably
want CMapFile initialized before CLogReader). This is a mistake on your
side, as C++ explicitly states, that no guarantee is given, which
constructor will be called first. Out of my head I'd propose one of the
following resolutions.

a) use local variables instead of globals and pass around
references/pointers. The order of initialization for local variables is
guaranteed.
b) use only ONE static object which agglomerates dependent objects,
like

class CLogReaderWithCMapFile {
CMapFile mapFile;
CLogReader logReader;
...
}

Here you have complete control over the order of initialization in
your constructor.

CLogReaderWithCMapfile (...):
mapFile (...),
logReader (...)
{
}

Btw, there's undoubtedly people who are going to tell you this is
off-topic, as it is MS specific. Just ignore them, that's just typical
"background noise" whenever people can tell, you are using MS products
(from the name of your dynamic library, .dll instead of .so). What has
hit you is a classical case of so called "undefined behaviour" in C++,
something totally on topic for this newsgroup ;-)

Dec 12 '06 #4
On Tue, 12 Dec 2006 04:33:58 -0800, F.J.K. wrote:
Allen schrieb:
>In a static library, there is a static variable definition.

static CLogger::mapFile;

In both EXE and DLL, I use the same code. CLogReader uses
CLogger::mapFile to do some work.
CLogReader logReader;

But the result is different.

[snip]

Btw, there's undoubtedly people who are going to tell you this is
off-topic, as it is MS specific.
How do we know it *isn't* MS specific since insufficient code was posted?
You yourself admit to making a "wild guess" (albeit quite likely a correct
one).
Just ignore them, that's just typical "background noise" whenever people
can tell, you are using MS products (from the name of your
dynamic library, .dll instead of .so).
Nonsense. You may well get (justifiable) complaints if your question is
evidently MS-specific, or Linux-specific, or
whatever non-C++-language-specific. If your query is on-topic nobody cares
what products you're using.
What has hit you is a classical case of so called "undefined behaviour"
in C++, something totally on topic for this newsgroup ;-)
....or maybe it's something MS-specific ;-)

--
Lionel B
Dec 12 '06 #5
Well, the following is a wild guess only, try to follow the guidelines
for posting on this newsgroup for better answers next time, (esp.
http://www.parashift.com/c++-faq-lit...t.html#faq-5.8)

It seems you have used two static variables of type CLogReader and
CMapFile and rely on the order of their initialization (you probably
want CMapFile initialized before CLogReader). This is a mistake on your
side, as C++ explicitly states, that no guarantee is given, which
constructor will be called first. Out of my head I'd propose one of the
following resolutions.

a) use local variables instead of globals and pass around
references/pointers. The order of initialization for local variables is
guaranteed.
b) use only ONE static object which agglomerates dependent objects,
like

class CLogReaderWithCMapFile {
CMapFile mapFile;
CLogReader logReader;
...
}

Here you have complete control over the order of initialization in
your constructor.

CLogReaderWithCMapfile (...):
mapFile (...),
logReader (...)
{
}

Yes. You are right. I cannot be sure that it is the right answer. But
it works. Thank you!
After I post this topic, I kept testing on this question. Now I find
out a solution.

In the .dll implementation, as you said, I used a global variable
CLogReader. It is the point. Now I changed it to be a local static
variable and a global pointer to solve the problem Below is the sample
codes.

/// previous version
CLogReader logReader;

DLL_EXPORT void InitLogReader()
{
logReader.InitLogReader();
}

DLL_EXPORT void ReadMesg()
{
logReader.ReadMesg();
}

/// corrected version
CLogReader* pLogReader = NULL;

DLL_EXPORT void InitLogReader()
{
static CLogReader logReader;
logReader.InitLogReader();

pLogReader = &logReader;
}

DLL_EXPORT void ReadMesg()
{
if (pLogReader == NULL)
{
printf("\nLogReader is not initialized");
return;
}
pLogReader->ReadMesg();
}

I think it is not easy to give the anwser to this question. Thank you
again.

Dec 13 '06 #6
Hi Allen,
I think the reason for this strange behaviour is caused by the way the
OS handles dlls and exes.
dll's are better for performance since they are initialized and
instantiated once (during their first call) and continue to operate to
serve all client programmes. Only one copy of the dll is running at any
one time. Exe's however, are treated just as any other programme is. A
fresh copy is instantiated in a separate memory space every time it's
required. This obviously has performance overhead.

So, if the constructor is called only the very first time the programme
is run, it will only run once in the case of a dll (that is when the
dll is called for the first time) and will be called every time the exe
is called (since a fresh copy of the exe will be created every time
it's needed).

In all fairness, I think this is more of a windows programming issue!
:o)

Cheers,
Madkour
Allen wrote:
Well, the following is a wild guess only, try to follow the guidelines
for posting on this newsgroup for better answers next time, (esp.
http://www.parashift.com/c++-faq-lit...t.html#faq-5.8)

It seems you have used two static variables of type CLogReader and
CMapFile and rely on the order of their initialization (you probably
want CMapFile initialized before CLogReader). This is a mistake on your
side, as C++ explicitly states, that no guarantee is given, which
constructor will be called first. Out of my head I'd propose one of the
following resolutions.

a) use local variables instead of globals and pass around
references/pointers. The order of initialization for local variables is
guaranteed.
b) use only ONE static object which agglomerates dependent objects,
like

class CLogReaderWithCMapFile {
CMapFile mapFile;
CLogReader logReader;
...
}

Here you have complete control over the order of initialization in
your constructor.

CLogReaderWithCMapfile (...):
mapFile (...),
logReader (...)
{
}


Yes. You are right. I cannot be sure that it is the right answer. But
it works. Thank you!
After I post this topic, I kept testing on this question. Now I find
out a solution.

In the .dll implementation, as you said, I used a global variable
CLogReader. It is the point. Now I changed it to be a local static
variable and a global pointer to solve the problem Below is the sample
codes.

/// previous version
CLogReader logReader;

DLL_EXPORT void InitLogReader()
{
logReader.InitLogReader();
}

DLL_EXPORT void ReadMesg()
{
logReader.ReadMesg();
}

/// corrected version
CLogReader* pLogReader = NULL;

DLL_EXPORT void InitLogReader()
{
static CLogReader logReader;
logReader.InitLogReader();

pLogReader = &logReader;
}

DLL_EXPORT void ReadMesg()
{
if (pLogReader == NULL)
{
printf("\nLogReader is not initialized");
return;
}
pLogReader->ReadMesg();
}

I think it is not easy to give the anwser to this question. Thank you
again.
Dec 13 '06 #7
Lionel B schrieb:
How do we know it *isn't* MS specific since insufficient code was posted?
You yourself admit to making a "wild guess" (albeit quite likely a correct
one).
Well, there wasn't enough code posted to be sure either way. However,
some guesses are "wilder" than others ;-) The OP was relying on order
of initializations. Order of constructor calls for global objects is a
pretty common pitfall of the language.
>
Just ignore them, that's just typical "background noise" whenever people
can tell, you are using MS products (from the name of your
...or maybe it's something MS-specific ;-)
To be honest, there probably will be some kind of "MS-specificity" to
the problem. Linking is notoriously underdefined by language
standards, you've got no chance to keep this area free of platform
specific information. But that's a problem of C++, too.

Dec 13 '06 #8
On Wed, 13 Dec 2006 07:56:24 -0800, F.J.K. wrote:
Lionel B schrieb:
>How do we know it *isn't* MS specific since insufficient code was posted?
You yourself admit to making a "wild guess" (albeit quite likely a correct
one).

Well, there wasn't enough code posted to be sure either way. However,
some guesses are "wilder" than others ;-) The OP was relying on order
of initializations. Order of constructor calls for global objects is a
pretty common pitfall of the language.
Just ignore them, that's just typical "background noise" whenever people
can tell, you are using MS products (from the name of your
What has hit you is a classical case of so called "undefined
behaviour" in C++, something totally on topic for this newsgroup ;-)

...or maybe it's something MS-specific ;-)

To be honest, there probably will be some kind of "MS-specificity" to
the problem. Linking is notoriously underdefined by language standards,
you've got no chance to keep this area free of platform specific
information. But that's a problem of C++, too.
As it turns out, the OP's problem had nothing to do with linking or
MS-specificity, but - as you correctly guessed - with the well-known
"gotcha" of global object initialisation order.

The point I was trying to make is that had the OP posted code we might have
spotted this straight off - and nobody would have had valid cause to
complain about MS-specificity since it would have been clear that this was
not the issue... this despite the fact that the OP himself seemed to think
it /was/ an MS-specific (or possibly linkage) thing and therefore
shouldn't have posted here! You might say he accidentally posted to the
correct forum through ignorance... :)

--
Lionel B
Dec 13 '06 #9

Lionel B schrieb:
not the issue... this despite the fact that the OP himself seemed to think
it /was/ an MS-specific (or possibly linkage) thing and therefore
shouldn't have posted here! You might say he accidentally posted to the
correct forum through ignorance... :)
sometimes, ignorance is bliss ;-)

Dec 14 '06 #10

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

Similar topics

7
by: BCC | last post by:
Hi, I have a class with several member variables that should be initialized according to user input before an object is instantiated. Using a static variable is required here. But, I would...
115
by: Mark Shelor | last post by:
I've encountered a troublesome inconsistency in the C-language Perl extension I've written for CPAN (Digest::SHA). The problem involves the use of a static array within a performance-critical...
4
by: Bryan Green | last post by:
So I'm working on a project for a C# class I'm taking, where I need to keep some running totals via static variables. I need three classes for three different types of objects. The base class and...
25
by: Sahil Malik [MVP] | last post by:
So here's a rather simple question. Say in an ASP.NET application, I wish to share common constants as static variables in global.asax (I know there's web.config bla bla .. but lets just say I...
8
by: Simone Chiaretta | last post by:
I've a very strange behaveour related to a website we built: from times to times, something should happen on the server, and all static variables inside the web application, both defined inside aspx...
6
by: Macca | last post by:
Hi, Are static variables thread safe? I have a static byte array. This will be accessed from more than one thread. Is it automatically thread safe by being static rather than an instance or do i...
9
by: CDMAPoster | last post by:
About a year ago there was a thread about the use of global variables in A97: http://groups.google.com/group/comp.databases.ms-access/browse_frm/thread/fedc837a5aeb6157 Best Practices by Kang...
3
by: juro | last post by:
Hi, I have a small problem: I'd like to call static variables from different classes - their names are stored in an array. Example of a class: class MyClass1{ public static $mysql_table =...
16
by: RB | last post by:
Hi clever people :-) I've noticed a lot of people stating not to use static variables with ASP.NET, and, as I understand it, the reason is because the variable is shared across user sessions -...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.