2

I am writing a program in c++, that stores different data in a binary file. I am running into issues because the size of a data type can change from one system to another. I was wondering if floats are always 4 byte on all windows platforms. The only platform i am building this program for is windows.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Popgalop
  • 737
  • 2
  • 9
  • 26

4 Answers4

3

Not guaranteed by the C++ standard, but most machines today follows ISO/IEC/IEEE 60559:2011, or the identical IEEE-754 floating point standard. By this standard, the single precision float is 4 bytes.

You can check std::numeric_limits< float >::is_iec559 in <limits> to make sure.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

Yes. Of course, it may be wise to throw a static_assert(sizeof(float)==4, "whatever") in there (or a plain old non-static assert, if the former is not supported by your compiler), just to (a) document your assumption, and (b) notify you if by some cruel twist of fate your platform suddenly does not have 4-byte floats.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 4
    Data type formats aren't determined by the operating system; they're determined by compilers. – Carey Gregory Oct 19 '13 at 13:22
  • 2
    I'm pretty sure that sooner or later *every* developer will stumble into a `#define float double /* more precision */` macro – peppe Oct 19 '13 at 13:41
  • @peppe perhaps, but that would be undefined behavior. :) – jalf Oct 20 '13 at 11:08
  • @CareyGregory: true, but the compiler (usually) doesn't make this decision in a vacuum. A sane compiler usually tries to stay compatible with the operating system's ABI, and the CPU's instruction set. It is certainly *possible* to create a compiler where a `float` has a different size, but on a CPU which works with 32-bit IEEE floating-point operands, and as long as you are not working on an OS which explicitly defines absurdly weird and contrived ABIs, it is a pretty safe assumption that your compiler will also use 4-byte `float`s – jalf Oct 20 '13 at 11:10
  • 1
    @jalf - substituting `double` for `float` is not undefined behavior. It's just a hideously bad programming practice, which we will all stumble upon sooner or later. – Carey Gregory Oct 22 '13 at 02:40
  • @CareyGregory re-#defining language keywords *is* undefined behavior. It is nothing specific to `float` and `double`. – jalf Oct 22 '13 at 07:18
  • @jalf We'll have to agree to disagree since using `double` in every instance where `float` is used will result in precisely the behavior defined for `double`. The only way you'd get undefined behavior would be if the usage of `float` were also undefined in that case. – Carey Gregory Oct 22 '13 at 14:29
  • @CareyGregory what a weird thing to say. Don't you care whether what you are saying is **correct**? The only thing that matters is what the C++ language specification says. What you or I "agree" with hardly matters to the compiler. So no, we will not have to agree to disagree. Not when we can find out what is actually correct. – jalf Oct 22 '13 at 14:42
  • @CareyGregory Now, after looking it up, the actual wording is a bit fluffy: as long as you do not include any standard library headers, you *may* be free to #define anything you like. But a TU which includes a std lib header yields undefined behavior if it defines a preprocessor macro with the same name as a keyword. (http://stackoverflow.com/questions/2726204/c-preprocessor-define-ing-a-keyword-is-it-standards-conforming/2726221#2726221). So yes, it is undefined behavior in any non-trivial code (anything that includes std lib headers), and *maybe* undefined if in other cases as well. – jalf Oct 22 '13 at 14:47
  • That is what the C++ language specification has to say on the matter. Unless you can find somewhere in the standard which contradicts this, then "agreeing" or "disagreeing" is nonsensical. – jalf Oct 22 '13 at 14:48
  • No, I'm not going to argue with the spec. So #defining keywords will produce undefined behavior in the std lib headers. OK, fine, but my point was that doing something like `#define float double` within your own code essentially has the exact same effect as using an editor to refactor all your `float`s to `double`s, and we know that does not _in and of itself_ produce undefined behavior. – Carey Gregory Oct 22 '13 at 17:15
  • @CareyGregory no, I didn't say "in std lib headers", I said "in translation units which **include** a std lib header". So no, `#define float double` does not have the effect you would expect. *That is what undefined behavior means*. The standard guarantees that `#define` works as you'd expect *as long as* you stay away from overriding those particular names with macros. If you do that, it is **not** guaranteed to be equivalent to using your IDE to refactor. `#define X Y` does *not* mean "blindly replace X with Y", it means "replace X with Y in the cases specified by the standard". – jalf Oct 23 '13 at 07:26
1

Yes it has 4 bytes only but it is not guaranteed. You may check the IEEE floating point for reference.

You can check by cross platform behavior like this:-

#include <cassert>
int main () {
    assert(sizeof(float) == 4);
    // If control goes here you can be sure float is 4 bytes.

}
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
0

Windows does not define the size of float -- your compiler defines that.

What Windows defines is a type named FLOAT in windef.h. It's defined as typedef float FLOAT;. That's the type name the Win32 API uses and the one you should be using if Windows support is important to you. I doubt any Windows compiler will ever change its format for float types, but Microsoft certainly could change their typedef for FLOAT and that would change what it means to support float on all versions of Windows.

Carey Gregory
  • 6,836
  • 2
  • 26
  • 47