Linda A. Walsh wrote: > > Bill McEnaney wrote: >> Maybe we need to distinguish between a const variable and a literal. That would IMO be a mistake. We should use the ISO terminology, which is "constant expression". >>>> if, in line 8, sizeof(days) is a constant, AND in line 9, >>>> sizeof(String) is >>>> a constant, then how can their division (in line 10) NOT be a constant? >>> Simple: sizeof(days) is a constant, but sizeof_days is not. Reason: >> because >>> the C language standard says so. A const variable is not a constant. >> It'd be > --- > Sorry to say, but whoever the 'rocket scientist' that thought up > this nonsense was, should be shot. Gosh, I hate sentences that begin "Sorry, but ..." :-) > I can use sizeof(days)/sizeof(String)-1 as a direct initializer into > a 'const' variable -- and THAT works: > typedef const char * String; > > static const String suffixes [] = {"B", "KB", "MB", "GB", "TB"}; > > static const int index_of_last_suffix = sizeof(suffixes)/(sizeof > (String)) - 1; > > As long as I don't try to assign "sizeof(suffixes)/sizeof(String) to > a 'const' declared integer, first, and then use that as an intermediate > step, I'm fine. But If I want to first assign the quotient to a const int > for 'num_items', and then use that value with "-1" to init a 2nd > constant, it fails. > > Sure seems like a C-design bug -- i.e. may be designed that way, but > it's certainly non-intuitive to see > const int a=b/c; > const int d=a-1; FAIL, while > const int d=b/c-1; works > > Certainly breaks or voids the concept of equivalent expressions being > equal. But they're not equivalent. The key thing to remember here: A const variable is not a constant. const in C is just a type qualifier. If there's one thing wrong here, it's that const is badly named: it really means "readonly". > Do I remember incorrectly, or is this fixed in C++? Yes, it is different in C++. Here's the C definition: "An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator." and the C++ definition: "An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used, and assignment, increment, decrement, function-call, or comma operators shall not be used." Andrew.