By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,003 Members | 1,163 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,003 IT Pros & Developers. It's quick & easy.

[Q] const declaration in .h file

P: n/a
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
salvor wrote:
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?


You may be running into "static object initialisation order fiasco".

When I run this:
----------------------
#include <iostream>
using namespace std;

typedef unsigned UInt32;

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };
const astruct astructarray[] = { keyA };
};

int main() {
cout << myns::astructarray[0].a << endl;
}
---------------------
I get '10'. So, the question is, where do you "loot at astructarray[0].a"
in your first reported case, when you get 0?

Victor
Jul 22 '05 #2

P: n/a
Victor Bazarov <v.********@comAcast.net> wrote:
salvor wrote:
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:
CASE #1

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:
CASE #2

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?
You may be running into "static object initialisation order fiasco".


This is what I figured might be happening.

Is there any guaranteed way to get out of this mess without moving
totally to the second case?

I liked the first case since it is useful to be able to use keyA itself
and be able to place keyA in an array. This way, if I needed to make a
change to keyA, I would not have to remember and correctly make the
change to the array as well.

I attempted to check the FAQ (http://www.parashift.com/c++-faq-lite/),
but it is unclear which major heading this topic would be covered under.
When I run this:
----------------------
#include <iostream>
using namespace std;

typedef unsigned UInt32;

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };
const astruct astructarray[] = { keyA };
};

int main() {
cout << myns::astructarray[0].a << endl;
}
---------------------
I get '10'. So, the question is, where do you "loot at astructarray[0].a"
in your first reported case, when you get 0?


Well, I am not sure how one "loot's", but I look at astructarray[0].a
well after my event driven application is underway and after I select an
item from a menu which has the code to look at astructarray[0].a.

Jul 22 '05 #3

P: n/a
Eric wrote:
Victor Bazarov <v.********@comAcast.net> wrote:
salvor wrote:
If you are the original poster, you might consider keeping the same
username, just for consistency. Unless these are your tow different
personalities posting, then I'd rather not comment.
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:


CASE #1

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:

CASE #2

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?


You may be running into "static object initialisation order fiasco".

This is what I figured might be happening.

Is there any guaranteed way to get out of this mess without moving
totally to the second case?

I liked the first case since it is useful to be able to use keyA itself
and be able to place keyA in an array. This way, if I needed to make a
change to keyA, I would not have to remember and correctly make the
change to the array as well.


What you did is initialised an element of the array with the same
value as in 'keyA'. Since an object with a namespace scope has static
storage duration, it is possible that a function in another module
will be called before 'astructarray' is initialised.

I attempted to check the FAQ (http://www.parashift.com/c++-faq-lite/),
but it is unclear which major heading this topic would be covered under.
FAQ # 10.15 talks about it. If you just searched by the word "fiasco",
you'd have found it.

When I run this:
----------------------
#include <iostream>
using namespace std;

typedef unsigned UInt32;

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };
const astruct astructarray[] = { keyA };
};

int main() {
cout << myns::astructarray[0].a << endl;
}
---------------------
I get '10'. So, the question is, where do you "loot at astructarray[0].a"
in your first reported case, when you get 0?

Well, I am not sure how one "loot's", but I look at astructarray[0].a
well after my event driven application is underway and after I select an
item from a menu which has the code to look at astructarray[0].a.


I don't know what "event driven application" is in terms of C++ and
how one "selects an item from a menu" (again in C++ terms). These
concepts are unknown as far as C++ _language_ is concerned. I showed
to you what happens in a C++ program when I print out the value of
the array element data member in question. How you _look_ at it,
again, is unknown. Perhaps if you specified what "looking" meant,
we would be on the same page.

Reduce the code you have to the bare minimum that exhibits the "error"
you originally posted about. Then post it here. IOW, follow the
recommendations of FAQ 5.8.

Victor
Jul 22 '05 #4

P: n/a
On Thu, 14 Oct 2004 12:49:18 -0400, sN************@verizon.net
(salvor) wrote:
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?


The problem is that "keyA" isn't a constant expression, so
astructarray isn't initialized at compile time, but at runtime. Hence
you run into the static initialization order fiasco. If you do it in
the second way, you are initializing astructarray with constant
expressions, so it is initialized at compile time, and there can't be
any problem.

You could put the 10 and 20 into separate variables. e.g.

const int a1 = 10;
const int a2 = 20; //note "a1" and "a2" are constant expressions
const astruct keyA = { a1, a2 };
const astruct astructarray[] = { {a1, a2} };

Unfortunately, you can only make constant expressions out of a few
things, like integral literals and the addresses of global objects.
However, const integral variables initialized with constant
expressions are also constant expressions (like "a1" above).

Tom
Jul 22 '05 #5

P: n/a
Eric wrote:
Victor Bazarov <v.********@comAcast.net> wrote:

salvor wrote:
I am attempting to figure out why this isn't working, because it seems
like it should be...

First I declare things similar to this:

CASE #1

struct astruct
{
UInt32 a;
UInt32 b;
};

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { keyA };
};

When I look at, astructarray[0].a, I get back a value of 0.

When I change this to:

CASE #2

namespace myns
{
const astruct keyA = { 10, 20 };

const astruct astructarray[] = { { 10, 20 } };
};

and look at astructarray[0].a, I get back a value of 10.
Why should things not work in the first case? Or should they?


You may be running into "static object initialisation order fiasco".

This is what I figured might be happening.

Is there any guaranteed way to get out of this mess without moving
totally to the second case?

I liked the first case since it is useful to be able to use keyA itself
and be able to place keyA in an array. This way, if I needed to make a
change to keyA, I would not have to remember and correctly make the
change to the array as well.


how about

namespace myns
{
const astruct astructarray[] = { { 10, 20 } };
const astruct& keyA = astructarray[0];
}
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.