Archived

This topic is now archived and is closed to further replies.

fallenang3l

Static duration variables

Recommended Posts

My book, C++ Primer Plus 4th edition, states (pg. 360) that all static variables can be initialized only with a constant expression such as a literal constant, const or enum constant and the sizeof operator. Then few pages later it makes this point: float * p_fees; // = new float[20] not allowed here [ed. because it''s not a const expression int main() { p_fees = new float[20]; ... However when I do some experimenting with VC 6.0, it turns out that I _can_ initialize the static storage variable p_fees with new float[20] at the point of its declaration even though the book states that is not possible. So my question is: is it really impossible to initialize statics with a non-const expression and the explanation why it works for me is that my VC 6.0 is simply not up to ANSI/ISO standards OR is the book wrong? Sorry if the question might sound n00bish to you but I''m just learning C++ on my own.

Share this post


Link to post
Share on other sites
I''m pretty sure the book is correct. Think of all static variables as pertaining to the rules of global variables. A global variable can''t be initialized with new, so neither can a static (however, static variables can be set to something non-constant later on).

Share this post


Link to post
Share on other sites
Anybody care to explain why the below works? It seems to go against all rules of logic:


  
#include <iostream>
using namespace std;

// Static storage with external linkage variable

// Everybody says you have to initialize it with a const expression

// but below seems to work.

float * p_fees = new float[20]; // block of 20 floats acquired, address

// of first float assigned to p_fees


int main()
{
p_fees[60] = 33.333f; // uh-oh, out of range, Windows XP Pro will complain with illegal operation

cout << p_fees[60] << endl; //but what is this... it seemed to work... Why?!?!?!?!?!? :-/

cout << p_fees[3] << endl; //some garbage displayed

return 0;
}


Share this post


Link to post
Share on other sites
It compiles in GCC 3.0.4 too. Maybe I''m wrong in some respect? I''ll go do some research and check what''s ''officially'' true. Now I need to find a copy of the C++ standard, since I only have the C99 one, heh.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
>// Static storage with external linkage variable
>// Everybody says you have to initialize it with a const expression
>// but below seems to work.
>float * p_fees = new float[20]; // block of 20 floats acquired, address of first float assigned to p_fees

p_fees is neither linked externally or static.

Share this post


Link to post
Share on other sites
I forgot to mention that I made it static and moved it into main during my testing (I assumed that he had forgotten that). Nothing I''ve seen in the standard covers this issue directly, and the most direct I''ve seen reiterates the ''constant value'' stuff.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
>// Static storage with external linkage variable
>// Everybody says you have to initialize it with a const expression
>// but below seems to work.
>float * p_fees = new float[20]; // block of 20 floats acquired, address of first float assigned to p_fees

p_fees is neither linked externally or static.


What you say ?
Here''s text from my book:
Variables with external linkage often are simply called external variables. They necessarily have static storage duration and file scope. External variables are defined outside of any function.
As far as I''m concerned, p_fees is declared outside of main, therefore it''s an external variable that _has to_ have static storage duration and file scope.
I don''t have to prefix the p_fees with the storage class specifier keyword static to make it, well, static. But if I did, it would just make it have internal linkage (exclusive the the translation unit in which it is declared) instead of external linkage (can be reference declared in any other translation units).

Share this post


Link to post
Share on other sites
The C++ Draft (since I don''t have the money for the complete standard ) says that constants are one of these:
--a null pointer value
--a null member pointer value
--an arithmetic constant expression,
--an address constant expression,
--a reference constant expression,
--an address constant expression for a complete object type, plus or minus an integral constant expression, or
--a pointer to member constant expression.

And an "address constant expression" is:
a pointer to an lvalue designating an object of static storage duration, a string literal, or a function.

So, I don''t see any exception to make an address returned by new into a constant. I''ve concluded (whether truthfully or not) that using new to initialize a static value isn''t allowed. This may be different in the full standard (like I said, I only can access the draft). You may want to ask this question on comp.lang.c++, since someone there may know and/or have a copy of the full standard.

Share this post


Link to post
Share on other sites

static int i = g_Obj->GetRandInteger();

Valid. Hmm...

Static variables can be instantiated to any value that can be concretely determined when the scope is first initialized. The book is wrong (and, AFAIK, has always been wrong - ie, you''ve always been able to initialize static variables as above).

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites