Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » static const float in C++. why not?

This thread is locked; no one can reply to it. rss feed Print
static const float in C++. why not?
Neil Walker
Member #210
April 2000
avatar

Hello,
The following code has compiled fine for me. All of a sudden after using VC8 it fails. But reading up on the error it's a perfectly valid error in the C++ specs. and nothing flaky about VC. The question is, why can integers be static consts but not floats?

class SomeClass {
public:
static const int MAXVEL=10; //ok
static const float FUEL_MAX=60.0; //fails (in VC8 its C2864)
...
};

I guess the other question, is what's the best way round it?

[edit]Fixed it. Apparently I remove the initialiser from the header file:
static const float FUEL_MAX;

Then in my .cpp code add it as:
const float Car::FUEL_MAX(60.0f);

How much of a pedantic f^ck is that! c++ is just stupid sometimes. It should be either all or nothing.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

CGamesPlay
Member #2,559
July 2002
avatar

class SomeClass {
public:
static const int MAXVEL=10;
static const float FUEL_MAX;
// ...
};

const float SomeClass::FUEL_MAX=60.0;

[append]
Bastard; thinking for yourself!

The reason is the same one you can't have global variables in header files. Where will it be initialized? With integers, the compiler can simply hard code the value into the program.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Neil Walker
Member #210
April 2000
avatar

Why can't floats be hard coded? it's just a number.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

CGamesPlay
Member #2,559
July 2002
avatar

To you, maybe, but to the processor, it's more complex. Floats aren't quite as complex as objects, but they still have separate instructions for dealing with them (for instance, one can increment (add 1 to) an integer, short, or char, but you can't do that to a float).

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Neil Walker
Member #210
April 2000
avatar

Cheers. Now I know :)

In the previous version of visual studio (2003) and in the version of GCC I used in devc++ the above worked ok.

[edit]
Actually, what I'm doing is going through the revisions of my code for a tutorial and this (revision 5 of 10) was the first time I added the const float. In the next version and onwards I had actually moved it as the code above mentioned, so I guess I must have upgraded to vc8 at that point and found the error!

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Bob
Free Market Evangelist
September 2000
avatar

It's a quirk of the C++ standard.

C++ Standard, Section 9.4.2.4 said:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constantinitializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

There is no such allowance for non-integral types.

--
- Bob
[ -- All my signature links are 404 -- ]

Neil Walker
Member #210
April 2000
avatar

Funny you should say that Bob, you're quoting the exact paragraph I found here:
http://www.thescripts.com/forum/thread263179.html

great minds must think alike ;)
(or read the same books)

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

To you, maybe, but to the processor, it's more complex. Floats aren't quite as complex as objects, but they still have separate instructions for dealing with them (for instance, one can increment (add 1 to) an integer, short, or char, but you can't do that to a float).

That, on the other hand, is a problem the compiler-maker has to deal with, not the programmer. The programmer has to deal with the quirk Bob describes, which is kind of a nice gesture towards compiler-makers.
And BTW, C++ does allow floats to be incremented; the fact that the compiler has to translate that into the appropriate instructions is a different story and has nothing to do with the problem at hand.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

That, on the other hand, is a problem the compiler-maker has to deal with, not the programmer. The programmer has to deal with the quirk Bob describes, which is kind of a nice gesture towards compiler-makers.
And BTW, C++ does allow floats to be incremented; the fact that the compiler has to translate that into the appropriate instructions is a different story and has nothing to do with the problem at hand.

You misunderstood why I was saying what I did. The reason for his problem not being in the standard may be completely arbitrary, btu in this case it isn't, and I was explaining why the decision to disallow non-integer types to be defined that was was made. The example involving increments was referring to the INC instruction, which doesn't exist for floats.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Arthur Kalliokoski
Second in Command
February 2005
avatar

fld1; faddp st1; (assuming the stack isn't full)

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Peter Wang
Member #23
April 2000

I still don't get it. Surely a float is just another bit pattern?

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

Surely a float is just another bit pattern?

And by that logic, so is a DivX movie. The different is the amount of work the processor has to undertake to manipulate them.

Quote:

fld1; faddp st1;

inc [ptr];

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Peter Wang
Member #23
April 2000

Fine, a float is a fixed width bit pattern. Initialising a machine word to hold the floating point representation of 1.0 should be no different to initialising it to hold a two's complement representation 1.

I'll admit, I don't know C++ very well. I thought all these were more-or-less equivalent:

#define FUEL_MAX 60.0

class SomeClass {
static const float FUEL_MAX=60.0;
}

const float SomeClass::FUEL_MAX=60.0;

What's the difference (modulo software engineering issues)?

CGamesPlay
Member #2,559
July 2002
avatar

The first is of course limited in its scope, and if I remember corrently, is a double. The second isn't valid :)

Quote:

Initialising a machine word to hold the floating point representation of 1.0 should be no different to initialising it to hold a two's complement representation 1.

But what if I want to have a static const struct and initialize it in the class? It's a fixed width bit pattern, too. Of course, it could have a constructor, so it would need to be initialized in a specific module. That's why static members need to be initialized outside the class declaration. And then where do the standard makers draw the line? They chose to do it after integers.

[append]
The reason integers are allow, I think, is that one can verbatim copy the constant value directly into the opcodes, and one can't do that with floats or any other data type.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Peter Wang
Member #23
April 2000

So the answer is, it's an arbitrary choice. Fine.

Bob
Free Market Evangelist
September 2000
avatar

It is an arbitrary choice; but not totally arbitrary. What happens when you use two different compilers to compile your object files, and then link them together? Will you get the same float value on both? What about the various (potentially different) compiler switches?

You can spec around those issues with integers, but it becomes much more complicated with floats.

--
- Bob
[ -- All my signature links are 404 -- ]

Peter Wang
Member #23
April 2000

Am I way off in thinking that integral static data members are allowed to facilitate simple inlining? I don't see why a non-inlined float value could work with an incompatible compiler... unless the linker is capable of rewriting floats from incompatible object files so they are of the right format?

[edit]
Found a partially satisfactory answer (to me) here:
http://www.thescripts.com/forum/thread141022.html

HoHo
Member #4,534
April 2004
avatar

I would think #defined constants are not 100% compatible with different compilers, as Bob said.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Arthur Kalliokoski
Second in Command
February 2005
avatar

Quote:

a float is a fixed width bit pattern. Initialising a machine word to hold the floating point representation of 1.0 should be no different to initialising it to hold a two's complement representation 1.

IIRC 1.0 should always be the same for IEEE (except endianness), but the arbitrary number you're adding 1 to will be different. Every time it passes a power of two, the exponent increments and the mantissa moves over as you successively add ones. Same as scientific notation, 1.0e+0 + 1.0e+0 = 2.0e+0, but 1.0e+0 + 1.0e+1 = 1.1e+1.

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Go to: