<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>sizeof(enum) -- Is it portable?</title>
		<link>http://www.allegro.cc/forums/view/348199</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sun, 04 Apr 2004 16:23:38 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If I use sizeof() for a binary read/write of an enumerated type variable, is this going to cause me problems with cross-platform compatibility?  Specifically, does GCC implement this consistently on different platforms?</p><p>P.S. I am fully aware that I could cast the variable as an integer, but I&#39;m doing a lazy IO like this:
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.delorie.com/djgpp/doc/libc/libc_371.html" target="_blank">fwrite</a><span class="k2">(</span><span class="k1">reinterpret_cast</span><span class="k3">&lt;</span><span class="k1">char</span><span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span><span class="k1">this</span><span class="k2">)</span>, <span class="k1">sizeof</span><span class="k2">(</span><span class="k1">struct</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
Which writes the struct as a single binary chunk.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ashteth)</author>
		<pubDate>Sat, 03 Apr 2004 23:26:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
You should never, <i>EVER</i> fwrite a struct to begin with.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (X-G)</author>
		<pubDate>Sat, 03 Apr 2004 23:32:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
Right. Always do it member by member.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (23yrold3yrold)</author>
		<pubDate>Sat, 03 Apr 2004 23:40:15 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That still doesn&#39;t solve his enum problem, and no, it will not be done the same way on all systems, perhaps.  GCC might do it the same way though.  The Win32 API&#39;s enums have a FORCE_DWORD enum, and they define it like so:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">enum</span> MyEnum <span class="k2">{</span>
  value <span class="k3">=</span> <span class="n">0</span>,
  value2 <span class="k3">=</span> <span class="n">1</span>,
  <span class="c">//etc</span>
  FORCE_DWORD <span class="k3">=</span> <span class="n">0xFFFFFFFF</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>
Or something like that.  That would make sure it is DWORD-sized or bigger I&#39;d think, and not the size of a DWORD.</p><p>Really you can&#39;t rely on sizeof(int) being the same and such.  This is one of the things that suck about C++.  You could try using some of the C99 types if your compiler supports them (I think Boost provides a wrapper for compilers that don&#39;t support it).  And I believe some of the C99 types guarantee a variable of an exact size.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Sat, 03 Apr 2004 23:52:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Johan peitz fwrites structs, and spellcaster considers fwriting structs a coding gem.</p><p>Boost has int&lt;num_of_bits&gt;_t types which provide cross-platform sizes and there&#39;s some header for C, maybe stdint.h, can&#39;t remember.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ron Ofir)</author>
		<pubDate>Sun, 04 Apr 2004 00:43:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>why do you say to not fwrite a struct?<br />i think that its one of the fastest way to write down a complicated data sequence
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (FMC)</author>
		<pubDate>Sun, 04 Apr 2004 01:23:28 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
Both Peitz and Lenny are wrong here, I&#39;d say. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>And as for your reasons why you would not want to ... every compiler and platform might use different schemes for 1) Endianness 2) Struct padding/alignment 3) Type sizes, and thus you can&#39;t guarantee that fwritten struct data will be compatible across compilers/platforms.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (X-G)</author>
		<pubDate>Sun, 04 Apr 2004 01:25:57 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>
If you try compiling your program with another compiler (or different version of your current compiler), you&#39;d better hope and pray those variables are the same size, use the same padding, etc. Otherwise, you&#39;re boned. Member by member is much safer. Slower, but safer.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (23yrold3yrold)</author>
		<pubDate>Sun, 04 Apr 2004 01:27:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>Johan peitz fwrites structs, and spellcaster considers fwriting structs a coding gem.</p></div></div><p>
Wirting structs to disk isn&#39;t disallowed, or illegal, or undefined. It&#39;s usually bad practice because most people doing it aren&#39;t aware of the consequences.</p><p>If you read/write structs to disk, you can no longer:<br />- Change compiler options<br />- Change compiler<br />- Change the struct or class in any way.<br />- Use pointers in that struct/class<br />- Use inheritence on that struct/class<br />- Use polymorphism on that struct/class<br />- Port files to other platforms.</p><p>Of course, if you can live with those restraints, then writing a struct/class to a file may be a good idea.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Bob)</author>
		<pubDate>Sun, 04 Apr 2004 01:28:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It is the fastest way to write down a complicated structure.  Sometimes it&#39;s also the only practical way to do so.  </p><p>It happens to also be really nasty in C / C++: </p><p>a.  The sizes of primitive items within a struct vary depending upon your platform, so files produced this way can&#39;t be shared across platform boundaries</p><p>b.  On some platforms the compiler may add invisible &quot;padding&quot; bytes to your structures... this can reduce efficiency, and result in a lack or portability similar to sizes of primitives issue.  </p><p>c.  There tends to be endianness portability issues if you use any primitives larger than 1 byte.  </p><p>d.  If your struct contains pointers... well... you&#39;ll have to handle that specially of course.  </p><p>e.  If you&#39;re using C++ and your struct has a virtual method or somesuch, then the type data (vtable pointer) will be included as well, but it may result in nasty nasty stuff: the correct value might not even be portable between different runs on the same computer using the same compiler.  </p><p>All that said, if you insulate your types by defining intermediates ala SDLs Uint32, C99s uint32_t or whatever, and you&#39;re carefully about alignment issues, and you don&#39;t use anything virtual, and you handle the endianness issues somehow, it IS possible to write fairly portable code that does raw fwrites with structs.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Sun, 04 Apr 2004 01:37:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks for the input guys. Currently my game architecture uses C++ style classes with parallel packed c style structs for IO.  This design works really well in combination with overloaded assignment operators. But as was pointed out, be careful:)</p><p>I forgot that endian issues may effect enums (if they&#39;re stored and presumably written as DWORDs), so perhaps I had best convert my enums to int64s.  I don&#39;t like doing 200 casts, but if I don&#39;t it will probably come back to haunt me sometime. BTW, thanks Gillus for the Boost C99 types wrapper idea. I&#39;ll definitely look into using those.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ashteth)</author>
		<pubDate>Sun, 04 Apr 2004 04:41:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I don&#39;t know why you would cast to 64-bit integers.  That&#39;s pretty excessive for an enum.  Depending on your enum you should be able to cast to unsigned char or unsigned short?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Sun, 04 Apr 2004 07:36:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>I forgot that endian issues may effect enums (if they&#39;re stored and presumably written as DWORDs), so perhaps I had best convert my enums to int64s.</p></div></div><p>
Which, apart from the insane memory usage, will not solve your endianesse problem.<br />Use Allegro&#39;s packfile functions for writing portable files (because you need to specify endianesse anyway).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Sun, 04 Apr 2004 16:23:38 +0000</pubDate>
	</item>
</rss>
