Jump to content
  • Advertisement
Sign in to follow this  
dbircsak

C union float trick?

This topic is 4611 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm looking through the Quake3 networking code and I come accross this:
void MSG_WriteFloat( msg_t *sb, float f ) {
	union {
		float	f;
		int	l;
	} dat;
	
	dat.f = f;
	MSG_WriteBits( sb, dat.l, 32 );
}
void MSG_WriteChar( msg_t *sb, int c ) {
#ifdef PARANOID
	if (c < -128 || c > 127)
		Com_Error (ERR_FATAL, "MSG_WriteChar: range error");
#endif

	MSG_WriteBits( sb, c, 8 );
}
void MSG_WriteLong( msg_t *sb, int c ) {
	MSG_WriteBits( sb, c, 32 );
}

The function I'm wondering about is MSG_WriteFloat... they declare a union, assign something to the float, and then send the int?! Why do they do this? Wait, I just realized I should look at the read function...
int MSG_ReadLong( msg_t *msg ) {
	int	c;
	
	c = MSG_ReadBits( msg, 32 );
	if ( msg->readcount > msg->cursize ) {
		c = -1;
	}	
	
	return c;
}

float MSG_ReadFloat( msg_t *msg ) {
	union {
		byte	b[4];
		float	f;
		int	l;
	} dat;
	
	dat.l = MSG_ReadBits( msg, 32 );
	if ( msg->readcount > msg->cursize ) {
		dat.f = -1;
	}	
	
	return dat.f;	
}
Again...they assign something to the int, but return the float??? I don't get it. How can they work with floats by using ints in a union variable? Thanks for the help, Darrell

Share this post


Link to post
Share on other sites
Advertisement
The read bits and write bits functions take ints (not floats). And with a union all the different possible objects share the same piece of memory (so changing one will change the others). And on the system they're using (x86) sizeof(float)=sizeof(int).

Edit ask if you need a clarification on the above, my description is terse.

Share this post


Link to post
Share on other sites
Just a warning...according to the C++ Standard assigning one type of a union and then reading another is undefined. Most compilers do what you would probably want/expect, but it would still be perfectly valid for an app to crash then.

Share this post


Link to post
Share on other sites
This is in fact illegal C++ (not sure about C), however most compilers support it because it's a common trick. The reason is that compilers can optimize by assuming variables of different types cannot alias to the same memory location, but in this case it's fairly easy for the compiler to handle.

Edit: beaten.

Share this post


Link to post
Share on other sites
The correct C++ way to do this would be to reinterpret_cast it to a float. In C, usually you would use *(int*)&f.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Promit
The correct C++ way to do this would be to reinterpret_cast it to a float. In C, usually you would use *(int*)&f.
Are you sure? I thought such reinterpret_casts were implementation defined? Wouldn't the proper method be to use a binary steam's operator <

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
(continued due to crappy handling of angled brackets in AP posts)
a binary stream's insertion operator? Is there a binary (in the file as text vs binary sense) equivalent of stringstream that could be used to convert POD types to some type of byte buffer?
-Extrarius

Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
The correct C++ way to do this would be to reinterpret_cast it to a float.


Really? In MSVC++7,


int i = 10;
float j = reinterpret_cast<float>(i);


gives me:

error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'float'

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1
Quote:
Original post by Promit
The correct C++ way to do this would be to reinterpret_cast it to a float.


Really? In MSVC++7,


int i = 10;
float j = reinterpret_cast<float>(i);


gives me:

error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'float'


You would use pointers.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!