Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > [Q] const declaration in .h file

Reply
Thread Tools

[Q] const declaration in .h file

 
 
salvor
Guest
Posts: n/a
 
      10-14-2004
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?



 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      10-14-2004
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
 
Reply With Quote
 
 
 
 
Eric
Guest
Posts: n/a
 
      10-14-2004
Victor Bazarov <(E-Mail Removed)> 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.



 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      10-14-2004
Eric wrote:
> Victor Bazarov <(E-Mail Removed)> 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
 
Reply With Quote
 
Tom Widmer
Guest
Posts: n/a
 
      10-14-2004
On Thu, 14 Oct 2004 12:49:18 -0400, http://www.velocityreviews.com/forums/(E-Mail Removed)
(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
 
Reply With Quote
 
red floyd
Guest
Posts: n/a
 
      10-14-2004
Eric wrote:
> Victor Bazarov <(E-Mail Removed)> 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];
}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
const correctness - should C++ prefer const member over non-const? fungus C++ 13 10-31-2008 05:33 AM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
Re: Declaration of "const A &B::A() const" changes meaning of A from "class A" Alexander Farber C++ 0 06-21-2005 07:35 AM



Advertisments