This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: C++ static integer class constants...


> A few days ago, I was writing a program that had some constants. They were
> all defined in a class and were static constant integers, something like
> 
> class foo {
> public:
>   static const int X = 5;
>   static const int Y = 10;
>   static const int Z = 15;
> };
> 
> When I would compile my program in Windows XP with mingw g++ 3.4.2, I
> would
> have no problems.
> 
> However, when I went to Linux, where I have g++ 3.3.5 (or possibly 3.3.6,
> but I think it's 3.3.5), the linker would complain about unresolved
> symbols.
> 
> If I were to define the static variable in my implementation file, the
> linker would find the variables and go on its merry way. In other words, I
> could solve the problem by doing this:
> 
> const int foo::X;
> const int foo::Y;
> const int foo::Z;
> 
> I didn't even need to declare a value here. It took the value from the
> class-def.
> 
> Is this correct behavior? I thought static constant integers could be
> defined completely within the class, because they are simply type-safe
> constants that need no storage space. It seems like it might have been
> wrong
> since in Windows I had g++ 3.4.2 and in Linux I had g++ 3.3.5, but I
> wasn't
> sure.
> 
> In Bruce Eckel's "Thinking in C++", he states that "In older versions of
> C++, static const was not supported inside classes." I don't generally
> think
> of g++ 3.3.x as an old compiler, but maybe it is just old enough not to
> support this?
> 
> Thanks,
> 
> --John Ratliff
>

> -----Original Message-----
> From: Ryan Mansfield [mailto:RMansfield@qnx.com]
> Sent: Sunday, October 16, 2005 10:26 AM
> To: 'John Ratliff'; gcc-help@gcc.gnu.org
> Subject: RE: C++ static integer class constants...
> 
> Yes, it is required that static data members must be defined in exactly
> one
> translation unit.
> 
> Please see:
> 
> http://gcc.gnu.org/onlinedocs/gcc/Static-Definitions.html#Static-
> Definitions
> 
> http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.11
> 
> Regards,
> 
> Ryan Mansfield

I am asking if static CONSTANTS are different than static member variables.
My understanding of a static constant is that it is like a type-safe local
define. It solves the major problems of #define for creating constants. They
should not need storage space.

And if I am wrong, and they do, then why do they only need storage space for
g++ <= 3.3.5 and not g++ 3.4.2? Is it just an optimization? g++ 3.4.2 never
needed storage space declared, even when I passed -O0 to it. g++ 3.3.5 only
needed storage for 2 of my 8 constants regardless of whether -O0 or -O2 was
used.

This is an example from Bruce Eckel's Thinking in C++ Volume 1. Why does
this program not need to declare storage space for StringStack::size? Is
Bruce Eckel wrong?

-----------------------------------------------
//: C08:StringStack.cpp
// Using static const to create a 
// compile-time constant inside a class
#include <string>
#include <iostream>
using namespace std;

class StringStack {
  static const int size = 100;
  const string* stack[size];
  int index;
public:
  StringStack();
  void push(const string* s);
  const string* pop();
};

StringStack::StringStack() : index(0) {
  memset(stack, 0, size * sizeof(string*));
}

void StringStack::push(const string* s) {
  if(index < size)
    stack[index++] = s;
}

const string* StringStack::pop() {
  if(index > 0) {
    const string* rv = stack[--index];
    stack[index] = 0;
    return rv;
  }
  return 0;
}

string iceCream[] = {
  "pralines & cream",
  "fudge ripple",
  "jamocha almond fudge",
  "wild mountain blackberry",
  "raspberry sorbet",
  "lemon swirl",
  "rocky road",
  "deep chocolate fudge"
};

const int iCsz = 
  sizeof iceCream / sizeof *iceCream;

int main() {
  StringStack ss;
  for(int i = 0; i < iCsz; i++)
    ss.push(&iceCream[i]);
  const string* cp;
  while((cp = ss.pop()) != 0)
    cout << *cp << endl;
} ///:~
-----------------------------------------------




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]