<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Portability Blog</title>
    <link>http://portabilityblog.com/blog/</link>
    <description>tales about building software on many platforms</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.2.1 - http://www.s9y.org/</generator>
    <managingEditor>df.portabilityblog@erinye.com</managingEditor>
<webMaster>df.portabilityblog@erinye.com</webMaster>
<pubDate>Wed, 23 Jun 2010 06:34:21 GMT</pubDate>

    <image>
        <url>http://portabilityblog.com/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Portability Blog - tales about building software on many platforms</title>
        <link>http://portabilityblog.com/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Perl exec</title>
    <link>http://portabilityblog.com/blog/archives/12-Perl-exec.html</link>
            <category>Compilers</category>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/12-Perl-exec.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=12</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=12</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    Perl is a popular scripting language in the UNIX world, and there are several ports available for Windows. If your UNIX project uses perl, then porting that code to Windows is fairly painless. Perl doesn&#039;t attempt to be entirely portable, but most of the differences are quite obvious.&lt;br /&gt;
&lt;br /&gt;
One that is apparently not obvious is perl&#039;s exec function. I&#039;ve seen this happen to two different projects recently, in short succession. The symptom was that a process was started by a perl script, but no output from it was recorded on Windows. On UNIX, everything worked as expected.&lt;br /&gt;
&lt;br /&gt;
This turns out to be not very complicated. On UNIX, exec is implemented in terms of the execl()/execv() family of syscalls. This means the child process replaces the parent, and any process waiting for that parent automatically waits for the child instead. On Windows, there is no such thing. Windows perl implements exec by spawning a child process and returning control to the parent immediately, which then exits. Any process waiting for the parent regains control instantly and is left unaware of the child. A script written for UNIX will assume that the work is done before it has even started.&lt;br /&gt;
&lt;br /&gt;
There is a simple workaround: Use system (plus exit, if necessary) instead of exec. While the semantics are slightly different from exec, they are at least the same on both platforms; system spawns a new process and then waits for it, returning its exit code. Notice that system has a list form too so you don&#039;t need to worry about shell escaping either. 
    </content:encoded>

    <pubDate>Wed, 23 Jun 2010 08:34:21 +0200</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/12-guid.html</guid>
    <category>perl</category>
<category>unix</category>
<category>windows</category>

</item>
<item>
    <title>Bad register name &quot;dil&quot; (or &quot;sil&quot;)</title>
    <link>http://portabilityblog.com/blog/archives/11-Bad-register-name-dil-or-sil.html</link>
            <category>CPUs</category>
    
    <comments>http://portabilityblog.com/blog/archives/11-Bad-register-name-dil-or-sil.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=11</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=11</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    This is a piece of code from a project that runs on both the x86 and x86_64 architectures:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;inline&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;swap_int&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;a&lt;span style=&quot;color:#000000&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; b&lt;span style=&quot;color:#000000&quot;&gt;) {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;    &lt;span style=&quot;color:#8f0055&quot;&gt;asm&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;volatile&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;xchg %0, %1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;+r&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;b&lt;span style=&quot;color:#000000&quot;&gt;) ,&lt;/span&gt; &lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;+m&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(*&lt;/span&gt;a&lt;span style=&quot;color:#000000&quot;&gt;));&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;    &lt;span style=&quot;color:#8f0055&quot;&gt;return&lt;/span&gt; b&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s fairly easy to see what it does: It swaps two values of type &lt;code&gt;int&lt;/code&gt;. This code works perfectly fine on both architectures, provided that you&#039;re using a compiler that understands the &lt;code&gt;asm&lt;/code&gt; statement, such as gcc. Later, this similar piece of code appears:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;inline&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;swap_char&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;char&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;a&lt;span style=&quot;color:#000000&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;char&lt;/span&gt; b&lt;span style=&quot;color:#000000&quot;&gt;) {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;    &lt;span style=&quot;color:#8f0055&quot;&gt;asm&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;volatile&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;xchg %0, %1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;+r&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;b&lt;span style=&quot;color:#000000&quot;&gt;) ,&lt;/span&gt; &lt;span style=&quot;color:#c00000&quot;&gt;&amp;quot;+m&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;(*&lt;/span&gt;a&lt;span style=&quot;color:#000000&quot;&gt;));&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;    &lt;span style=&quot;color:#8f0055&quot;&gt;return&lt;/span&gt; b&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
This code still compiles and works just fine. For the most part. But when optimisation is turned on, you may get this error from gcc when building for x86:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;code&gt;Error: bad register name `%dil&#039;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
Then you try the same on x86_64 and the error is gone again. No wonder: As opposed to x86, the x86_64 architecture actually has the %dil register.&lt;br /&gt;
&lt;br /&gt;
At first, this appears to be a compiler bug. After all, the compiler is choosing a register that doesn&#039;t exist on x86. On closer look, it&#039;s a bug in the example code. The issue is that for the &lt;code&gt;b&lt;/code&gt; argument, the constraint &lt;code&gt;r&lt;/code&gt; is used, indicating that the value should be stored in any general-purpose register. In the first example, this is just fine. All of them will do for 32-bit operations. The second example, on closer examination, actually requires a register whose lower byte is accessible. On x86, there are only four general-purpose registers where this is true: EAX, EBX, ECX and EDX. On x86_64, this is also true for the ESI and EDI registers that are also treated as general-purpose registers on x86.&lt;br /&gt;
&lt;br /&gt;
So what happens is that the compiler correctly chooses the &lt;code&gt;%edi&lt;/code&gt; register, which satisfies the &lt;code&gt;r&lt;/code&gt; constraint. Later, the &lt;code&gt;xchg&lt;/code&gt; instruction is interpreted as referring to two byte-sized values due to the size of the arguments &lt;code&gt;*a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;. Thus, the compiler translates the instruction to its 8-bit form and replaces the register placeholder &lt;code&gt;%0&lt;/code&gt; with the 8-bit form of the &lt;code&gt;%edi&lt;/code&gt; register, which is &lt;code&gt;%dil&lt;/code&gt;. During assembly, this fails because &lt;code&gt;%dil&lt;/code&gt; doesn&#039;t actually exist on x86.&lt;br /&gt;
&lt;br /&gt;
If there is a compiler bug, it is only that the error output is misleading. It shouldn&#039;t even try to use &lt;code&gt;%dil&lt;/code&gt;, it should warn about the real problem. &lt;br /&gt;
&lt;br /&gt;
The real bug is that in the example source, a byte-sized argument was qualified with a constraint that allowed any general-purpose register to be used, where instead, the set should be constrained to registers whose lower byte is available. In gcc, this can be achieved by using the &lt;code&gt;q&lt;/code&gt; constraint instead of &lt;code&gt;r&lt;/code&gt;. 
    </content:encoded>

    <pubDate>Fri, 29 May 2009 13:09:23 +0200</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/11-guid.html</guid>
    <category>32 bit</category>
<category>64 bit</category>
<category>gcc</category>
<category>x86</category>
<category>x86_64</category>

</item>
<item>
    <title>SO_SNDTIMEO and SO_RCVTIMEO</title>
    <link>http://portabilityblog.com/blog/archives/10-SO_SNDTIMEO-and-SO_RCVTIMEO.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/10-SO_SNDTIMEO-and-SO_RCVTIMEO.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=10</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=10</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    Implementations of the BSD socket interface support various socket options. Two of them are SO_SNDTIMEO and SO_RCVTIMEO. They allow the user to specify a timeout for otherwise blocking send() and recv() calls. They&#039;re often described as the two socket options that have the most different implementations and are therefore among the most unportable ones at all.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
It&#039;s not quite as bad, but among the major UNIX and Unix-like operating systems, there are at least three different beaviours for stream sockets, ignoring that the behaviour for datagram sockets may yet be different.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Most of the operating systems I tested this on actually support these timeouts. Mac OS X, Linux, FreeBSD and AIX were all among the platforms where I was able to use these timeouts in a simple test, using reasonably recent versions of these operating systems. This means that the OSes accepted setting the option and the timeout that was configured did actually work. The BSD socket implementation that is used in Microsoft Windows also falls into this category, the timeouts work reliably there.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
One notable exception was Solaris, which reported that the protocol did not support this option. This means that the setsockopt() call failed. Since this is detectable, it&#039;s not a problem; there are other ways to implement timeouts without support from the socket layer.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
The other notable exception was HP-UX (tested with 11iv3 and 11iv1). On HP-UX, you can get the same behaviour as on Solaris if you use the UNIX03 socket library, meaning setsockopt() fails with ENOPROTOOPT. However, if you&#039;re using the BSD socket library that is also provided with HP-UX, then you &lt;i&gt;are&lt;/i&gt; allowed to set the timeouts, but they are silently ignored.&lt;br /&gt;
&lt;br /&gt;
Even worse, the system will remember the timout you set, and querying it with getsockopt() will return it. This means you can&#039;t verify that the timeout is available by querying it after setting it and comparing it to the value you set it to. Setting it is allowed and querying it will yield the timeout that was previously set, but &lt;i&gt;the timeout setting will be silently ignored by HP-UX&lt;/i&gt;.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
&lt;b&gt;In summary,&lt;/b&gt; you can actually expect these timeouts to either work or cause an error when you try to set them on most UNIX and Unix-like operating systems, and also on Windows, but if you are really concerned about portability, you need a backup plan, and either a whitelist of platforms where the backup plan is not necessary, or a very short blacklist that mostly consists of HP-UX.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Tue, 24 Mar 2009 13:30:29 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/10-guid.html</guid>
    <category>bsd</category>
<category>hp-ux</category>
<category>sockets</category>
<category>unix</category>

</item>
<item>
    <title>Version Number Formatting</title>
    <link>http://portabilityblog.com/blog/archives/9-Version-Number-Formatting.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/9-Version-Number-Formatting.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=9</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=9</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    One thing that&#039;s biting me currently is imposed version number formatting. The product I&#039;m working on uses the traditional Major-Minor-Patch format, that is, there are three numerical components in a version number. Additionally, we add a suffix for special builds based on a previous release, such as a single letter for a hotfix build, or a service pack identifier, or a support ticket identifier.&lt;br /&gt;
&lt;br /&gt;
Getting software certified for Windows Vista necessitates including a manifest with the software that, among other information, contains the name of the executable, the version number, security settings, and a signature. The version number consists of four components: Major, minor, build and revision. The version number goes into an XML attribute, so one programmer apparently forgot to double-check and put in our regular three-component version number.&lt;br /&gt;
&lt;br /&gt;
Needless to say, we figured that out fairly fast, since Windows 2003 will refuse to run applications with embedded manifests that contain errors. Interestingly, the tool that actually embeds the manifest doesn&#039;t comment at all. And the error that you get from Windows is not very transparent - you have to look into the system event log to get a clue, and unless you&#039;re on Vista, the clue you&#039;re getting is only that there&#039;s &lt;i&gt;something&lt;/i&gt; wrong with your manifest. Anyway, we just added a zero as the fourth component and all was well.&lt;br /&gt;
&lt;br /&gt;
Over time, we started to use an 1 instead of a 0 as the fourth component for a revision based on a previous release.&lt;br /&gt;
&lt;br /&gt;
Some time later, we figured out that we actually have multiple different types of revisions. So now, the fourth component is calculated from all of them (or, all of those that we thought of, so far). It&#039;s starting to look like a bit field. Of course, the &quot;revision&quot; field is completely meaningless for comparison purposes: Revision 100 is based on completely different changes to the source code than Revision 1. Granted, you can still tell from revision 101 that it includes both sets of updates, but at this point I&#039;m just glad that our other platforms aren&#039;t as limiting. 
    </content:encoded>

    <pubDate>Fri, 18 Jan 2008 12:01:51 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/9-guid.html</guid>
    <category>vista</category>
<category>windows</category>

</item>
<item>
    <title>O_DIRECT</title>
    <link>http://portabilityblog.com/blog/archives/8-O_DIRECT.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/8-O_DIRECT.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=8</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=8</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    On UNIXoid operating systems, you can open(2) a file in many modes. On some operating systems, one of them is O_DIRECT, which stands for direct i/o without any caching. To sum it all up:&lt;br /&gt;
&lt;blockquote&gt;The whole notion of &quot;direct IO&quot; is totally braindamaged. Just say no. --&lt;a href=&quot;http://lkml.org/lkml/2007/1/10/233&quot;&gt;Linus Torvalds&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;
Accessing files that were opened with O_DIRECT requires aligned buffers for reading and writing. For example, on Linux 2.6, all buffers must be aligned to 512 bytes and reads and writes can only happen in multiples of 512 bytes. It&#039;s fairly easy to align your data to 512 bytes, though.&lt;br /&gt;
&lt;br /&gt;
On Linux 2.4, on the other hand, buffers have to be aligned to multiples of the underlying file system&#039;s logical block size - which is generally much larger than 512 bytes. Size also has to be a multiple of the block size. It&#039;s not so easy to solve this generally. It&#039;s also often forgotten because nobody wants to use Linux 2.4 anymore, at least not for development work.&lt;br /&gt;
&lt;br /&gt;
We ran into this problem at least three times in three different places in 2007. You can tell that I work for a database company.&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Fri, 28 Dec 2007 11:03:47 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/8-guid.html</guid>
    <category>linux</category>

</item>
<item>
    <title>socklen_t confusion</title>
    <link>http://portabilityblog.com/blog/archives/7-socklen_t-confusion.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/7-socklen_t-confusion.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=7</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=7</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    The BSD socket API (accept, bind, and so on) uses a struct sockaddr to pass socket addresses. Additionally, there&#039;s a parameter for passing the size of the memory block allocated for a struct sockaddr to the socket functions. This argument is passed as a pointer to the actual size, and upon completion of the API call, will contain the actual length of the address stored in the memory block instead of its size. In the original BSD API, this argument was of type int *.&lt;br /&gt;
&lt;br /&gt;
At one point, a draft of the POSIX.1g standard defined this to be size_t *. This was a bit broken because size_t is usually not the same type as int on 64-bit platforms, the re-definition thus resulting in an unintended and incompatible change. The short of it is that people complained, and the type was changed again. Instead of reverting to int *, however, a new type socklen_t was introduced. This new type is defined to be the same as int on most platforms. As Linus Torvalds puts it,&lt;br /&gt;
&lt;blockquote&gt;_Any_ sane library _must_ have &quot;socklen_t&quot; be the same size as int. Anything else breaks any BSD socket layer stuff. POSIX initially did make it a size_t, and I (and hopefully others, but obviously not too many) complained to them very loudly indeed. Making it a size_t is completely broken, exactly because size_t very seldom is the same size as &quot;int&quot; on 64-bit architectures, for example. And it has to be the same size as &quot;int&quot; because that&#039;s what the BSD socket interface is.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
(Quote taken from man 2 accept on Linux.)&lt;br /&gt;
&lt;br /&gt;
So for a small period of time, operating system vendors were preparing for POSIX.1g as it was known back then and started to use size_t instead of int. As the draft was changed to use socklen_t, and later SUSv2 included socklen_t, they mostly started to use socklen_t and defined it to int. Some defined it to be the same type as size_t. One example that is mentioned in Linux&#039; man 2 accept is SunOS 5. This includes the current release of Solaris, being based on SunOS 5.10. However, that&#039;s not a &lt;i&gt;big&lt;/i&gt; portability issue. It&#039;s broken as described above, but code that uses socklen_t in all places should be just fine.&lt;br /&gt;
&lt;br /&gt;
On HP-UX, you get the worst of both worlds. On the one hand, you can use the old BSD API with pointers to int. On the other hand, you can define _XOPEN_SOURCE_EXTENDED and get the new API with socklen_t. However, if you don&#039;t define _XOPEN_SOURCE_EXTENDED, you still get a definition of socklen_t to size_t.  The type exists but is completely worthless as it can&#039;t be used with the socket API, which expects int.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve actually seen code that fell over this in both possible ways, using int * in one place and socklen_t * in another...&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Sat, 22 Dec 2007 14:22:00 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/7-guid.html</guid>
    <category>hp-ux</category>
<category>posix</category>

</item>
<item>
    <title>UNIX domain sockets</title>
    <link>http://portabilityblog.com/blog/archives/4-UNIX-domain-sockets.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/4-UNIX-domain-sockets.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=4</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=4</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    Unlike sockets in other domains, sockets in the UNIX domain are visible in the file system. Because of this, they&#039;re sometimes confused with regular files. When they&#039;re not being confused with regular files, their specific restrictions that don&#039;t apply to other files are still easily forgotten. One such restriction of a UNIX domain socket is the length of its name.&lt;br /&gt;
&lt;br /&gt;
Path names can be rather long on UNIX-like systems these days. Gone are the days of file names limited to 14 characters and for path names, POSIX-compliant operating systems generally support up to 256 characters. On many platforms, path names can be even longer than that. For example, PATH_MAX is 1024 on Mac OS X and 4096 on GNU/Linux. &lt;br /&gt;
&lt;br /&gt;
In contrast, the full path name of a UNIX domain socket must fit into a struct sockaddr_un. Its component sun_path generally has much less room for the socket&#039;s name than 1024 characters. Typical numbers are 108 (Linux, Solaris, Cygwin), 104 (AIX, BSDs, Mac OS X), and 92 (HP-UX). At some point, it was only 14 in &lt;a href=&quot;http://en.wikipedia.org/wiki/Interix&quot;&gt;Interix&lt;/a&gt; 5.2.&lt;br /&gt;
&lt;br /&gt;
This means that, while UNIX domain sockets do appear as if they were files, they can&#039;t be placed in an arbitrary location in the file system. Now, imagine an automated testing process that can test multiple instances of the software at a time, and keeps all files relevant to one test run within one directory. Path names can easily become longer than 92 characters in a scenario like this. In one case, this happened in a system where the name of one such instance&#039;s directory didn&#039;t have a constant length and occasionally brought the complete path to more than 92 characters, causing random total failures on HP-UX.  
    </content:encoded>

    <pubDate>Wed, 19 Dec 2007 12:05:00 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/4-guid.html</guid>
    <category>ipc</category>
<category>unix</category>

</item>
<item>
    <title>Denormal Numbers</title>
    <link>http://portabilityblog.com/blog/archives/5-Denormal-Numbers.html</link>
            <category>Compilers</category>
            <category>CPUs</category>
    
    <comments>http://portabilityblog.com/blog/archives/5-Denormal-Numbers.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=5</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=5</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    In school, we learned that x - y = 0 is true if, and only if, x = y. In computing, we learned that we can only store so many accurate digits in a fixed-size register. For example, a register that is 8 bits wide can store exactly 256 different values. If we want to represent negative and positive values, there are a number of ways to express that, but we&#039;ll still only get 256 different individual values. The way computers typically do it will give us values from -128 to +127. &lt;br /&gt;
&lt;br /&gt;
Now we might want to represent real numbers like 1.5. There&#039;s no way to get more than 256 different values from 8 bits, but we could agree that there&#039;s a decimal point, and it is always before the last digit. Instead of -128 to +127, we get -12.8 to 12.7. We traded in range for accuracy. Sometimes, range is more important than accuracy. In such a case, we could pretend that the decimal point is always one digit to the right of the last digit we store, giving us a range from -1280 to 1270. Our range got boosted, but we lost accuracy: We can no longer store numbers like 1234, even though it is in the range of our type. This is adequately refered to as &lt;i&gt;fixed point arithmetics&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Now, how do we get both range, and accuracy? Instead of putting the decimal point in a fixed location, we could instead store its position together with the actual number. This is called &lt;i&gt;floating point arithmetics&lt;/i&gt;. For example, we could say that we use 2 bits for the position of the decimal point, and 6 bits for the actual number. The way computers really do it is a bit more complex and is defined in &lt;a href=&quot;http://en.wikipedia.org/wiki/IEEE_754&quot;&gt;IEEE 754&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
IEEE 754 contains one detail that might not be obvious. Floating point numbers are represented by a sign bit, an exponent to a fixed and previously agreed-upon base, and a mantissa. However, the mantissa isn&#039;t just a number that is shifted left or right based on the exponent. Instead, it is defined that the mantissa is a number between including 1, and excluding 2. Since this means there&#039;s always one digit before the decimal point that can only be 1, the part that is stored is only the digits &lt;i&gt;after&lt;/i&gt; the decimal point. A number stored like this is called a &lt;i&gt;normal number&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
For simplicity, let&#039;s assume a similar system based on base 10. Let&#039;s say we can store the sign, exponents from -2 to +2, and we have room for a mantissa of three digits. This will let us express numbers from -1.999 * 10 ^ -2 to + 1.999 * 10 ^ 2. We can express x = 0.012 as 1.2 * 10 ^ -2 and y = 0.0105 as 1.05 * 10 ^ -2. &lt;br /&gt;
&lt;br /&gt;
However, we can&#039;t represent  x - y = 0.0015! Normalising it and writing it as 1.5 * 10 ^ -3 fails to satisfy the condition we agreed upon previously that we would only have exponents from -2 to +2. We&#039;ll have to live with it and just accept that the result of this computation is smaller than the smallest allowed number that we can represent, and replace it with zero. But x and y aren&#039;t equal!&lt;br /&gt;
&lt;br /&gt;
This is a terrible situation for scientists, and thus, a solution was quickly found. Basically, it goes like this: We sacrifice one of our possible exponent values, and use it instead to indicate that the number we represent isn&#039;t normalised as agreed upon before, and smaller than the smallest possible normalised number.  Such a number is called a &lt;i&gt;denormal number&lt;/i&gt;. &lt;br /&gt;
&lt;br /&gt;
You might wonder where the lesson is - after all, the problem seems to be solved. By introducing denormals, we fixed our condition from the first paragraph, and now it holds again for all x and y that can be represented individually.&lt;br /&gt;
&lt;br /&gt;
In theory, all major platforms of today support denormals. In practice, many CPUs don&#039;t handle them in hardware, but instead trap to some software implementation. Implementing floating point operations in software can be rather slow. Programmers, however, don&#039;t like their programs running slowly and tell compilers to optimise. Compilers for CPUs that trap when denormals occur know that they&#039;re slow, and therefore, optimise by turning of denormals altogether. Instead, results of calculations that can&#039;t be normalised are flushed to zero.&lt;br /&gt;
&lt;br /&gt;
For example, on Itanium CPUs, the x - y operation can be slower by orders of magnitude if the result is a denormal as compared to the same operation when the result can be expressed as a normal number. Here&#039;s some (rather simple) code to try this if you have access to an Itanium box. Compile with gcc, without optimisation, once with -DSMALL, once without, and then compare the run time. It&#039;s not a proper benchmark, but should be sufficient to show the problem.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;#include &amp;lt;math.h&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;() {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;double&lt;/span&gt; x&lt;span style=&quot;color:#000000&quot;&gt;, *&lt;/span&gt;y&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 6 &lt;/span&gt;  y &lt;span style=&quot;color:#000000&quot;&gt;= &amp;amp;&lt;/span&gt;x&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 7 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 8 &lt;/span&gt;  &lt;span style=&quot;color:#733710&quot;&gt;#ifdef SMALL&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 9 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;double&lt;/span&gt; a &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;1022&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;) +&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;1023&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;10 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;double&lt;/span&gt; b &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;1022&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;11 &lt;/span&gt;  &lt;span style=&quot;color:#733710&quot;&gt;#else&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;12 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;double&lt;/span&gt; a &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;122&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;) +&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;123&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;13 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;double&lt;/span&gt; b &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;,-&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;122&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;14 &lt;/span&gt;  &lt;span style=&quot;color:#733710&quot;&gt;#endif&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;15 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;16 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; i &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;17 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;i&lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt; i&lt;span style=&quot;color:#000000&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#2300ff&quot;&gt;10000000&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;; ++&lt;/span&gt;i&lt;span style=&quot;color:#000000&quot;&gt;) {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;18 &lt;/span&gt;    &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;y &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; a &lt;span style=&quot;color:#000000&quot;&gt;-&lt;/span&gt; b&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;19 &lt;/span&gt;  &lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;20 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;21 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;22 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
However, the vendor compiler for Itanium, Intel&#039;s icc, knows about this. When you use -O3 with icc on ia64, it enables flush to zero mode, which results in all denormal results to be flushed to zero. Use the same compiler on x86_64 and it won&#039;t, because x86_64 can handle denormals faster. It&#039;s still measurable, but not as much of a problem.&lt;br /&gt;
&lt;br /&gt;
I saw this problem in a test case that expected a denormal number as a result, and therefore failed (only) on ia64 with optimisation. It&#039;s still possible to get icc to optimise without enabling flush to zero mode, by specifically disabling it with the -no-ftz flag.&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Mon, 17 Dec 2007 15:56:00 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/5-guid.html</guid>
    <category>floating point</category>
<category>ia64</category>
<category>icc</category>

</item>
<item>
    <title>sizeof(long)</title>
    <link>http://portabilityblog.com/blog/archives/3-sizeoflong.html</link>
            <category>Compilers</category>
    
    <comments>http://portabilityblog.com/blog/archives/3-sizeoflong.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=3</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=3</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    It should be an offense to rely on the size of a given type in C to be the same across different platforms. Still, certain assumptions appear to be fairly common. One of them is the value of sizeof(long). I think we&#039;ve gotten over the idea that long and int are the same size now that 64 bit platforms are becoming more and more common. However, occassionally I still encounter a similar misconception: That the sizes of long and any pointer type are the same.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;#define S(X) printf(#X&lt;/span&gt; &lt;span style=&quot;color:#733710&quot;&gt;&amp;quot; %d&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#733710&quot;&gt;, sizeof(X))&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;() {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;  &lt;span style=&quot;color:#000000&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 6 &lt;/span&gt;  &lt;span style=&quot;color:#000000&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;long&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 7 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 8 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
This snippet will tell you that both a long and a pointer to int are of size 4 on most 32 bit platforms, and that both are of size 8 on most 64 bit platforms. There is one notable platform where this isn&#039;t the case. When compiled with Visual Studio&#039;s cl.exe on 64 bit Windows, the size of the pointer will be 8, but the size of the long will be 4.&lt;br /&gt;
&lt;br /&gt;
According to the C standard, this is perfectly legal. In reality, I&#039;ve seen variables of type long used to store pointers, or anything else that fits into a long on one of the other platforms. Please stop doing that, it&#039;s wrong, and it will break on Windows. 
    </content:encoded>

    <pubDate>Sun, 16 Dec 2007 11:00:00 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/3-guid.html</guid>
    <category>64 bit</category>
<category>visual studio</category>
<category>windows</category>

</item>
<item>
    <title>transparent_union</title>
    <link>http://portabilityblog.com/blog/archives/2-transparent_union.html</link>
            <category>Operating Systems</category>
    
    <comments>http://portabilityblog.com/blog/archives/2-transparent_union.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=2</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=2</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    Let&#039;s say you&#039;re writing a function that accepts a pointer to an int.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;do_stuff_with_int&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;p&lt;span style=&quot;color:#000000&quot;&gt;) {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;  &lt;span style=&quot;color:#007f1c&quot;&gt;/* ... */&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Later, you notice that the doing stuff operation doesn&#039;t depend on signedness at all, and decide that you want to use your function with unsigned int too. Just passing a pointer to an unsigned int will cause a warning. How would you get rid of it in a clean way? Easy, use a union.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;typedef&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;union&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;si&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;unsigned int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;ui&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt; signed_or_unsigned_int_pointer&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Now you have a type that can both contain a pointer to an int, or a pointer to an unsigned int. Wouldn&#039;t it be convenient if you could use your shiny new type to indicate that do_stuff_with_int() really can accept both types? That&#039;s where gcc&#039;s transparent_union attribute comes in. (Some other compilers also support this.)&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;typedef&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;union&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;si&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;unsigned int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;ui&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt; signed_or_unsigned_int_pointer
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;__attribute__&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;((&lt;/span&gt;transparent_union&lt;span style=&quot;color:#000000&quot;&gt;));&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 6 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 7 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;do_stuff_with_int&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&lt;/span&gt;signed_or_unsigned_int_pointer p&lt;span style=&quot;color:#000000&quot;&gt;) {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 8 &lt;/span&gt;  &lt;span style=&quot;color:#007f1c&quot;&gt;/* ... */&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 9 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;10 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;11 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;() {&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;12 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; a &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;13 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;unsigned int&lt;/span&gt; b &lt;span style=&quot;color:#000000&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;14 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;15 &lt;/span&gt;  &lt;span style=&quot;color:#000000&quot;&gt;do_stuff_with_int&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&amp;amp;&lt;/span&gt;a&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;16 &lt;/span&gt;  &lt;span style=&quot;color:#000000&quot;&gt;do_stuff_with_int&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;(&amp;amp;&lt;/span&gt;b&lt;span style=&quot;color:#000000&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;17 &lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;18 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#2300ff&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt;19 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Now, what&#039;s the catch? You can only use transparent_union with unions that contain only types with the same representation. In other words, they need to be the same size. You can&#039;t, for example, use it with a 32-bit int and a 64-bit integer, in which case gcc will generate a warning. And lots of errors later on, because you&#039;re not passing unions to your function, but any one of their constituent types, which isn&#039;t allowed without transparent_union.&lt;br /&gt;
&lt;br /&gt;
And now, the reason why this post is related to portability:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;typedef&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;union&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; an_int&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;long&lt;/span&gt; a_long&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt; int_union
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;__attribute__&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;((&lt;/span&gt;transparent_union&lt;span style=&quot;color:#000000&quot;&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The transparent_union attribute will be ignored on most 64 bit platforms.&lt;br /&gt;
&lt;br /&gt;
Treating int and long as the same type is a beginner&#039;s mistake. But what about this code?&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;&lt;span style=&quot;color:#8f0055&quot;&gt;typedef&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;union&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;{&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;volatile&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;i&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;  &lt;span style=&quot;color:#8f0055&quot;&gt;unsigned int&lt;/span&gt; &lt;span style=&quot;color:#8f0055&quot;&gt;volatile&lt;/span&gt; &lt;span style=&quot;color:#000000&quot;&gt;*&lt;/span&gt;u&lt;span style=&quot;color:#000000&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;}&lt;/span&gt; int_union
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;__attribute__&lt;/span&gt;&lt;span style=&quot;color:#000000&quot;&gt;((&lt;/span&gt;transparent_union&lt;span style=&quot;color:#000000&quot;&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Should work, shouldn&#039;t it?&lt;br /&gt;
&lt;br /&gt;
Turns out it doesn&#039;t. That is, it works in most places. It even works on Mac OS X. Unless you build for the 64-bit PowerPC CPU. In that case, the attribute is ignored, even though the two types are still the same size. This only seems to happen on ppc64. On all three other architectures currently supported by Mac OS X, it works.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;font-size:9pt;&quot;&gt;&lt;span style=&quot;color:#808080&quot;&gt; 1 &lt;/span&gt;$ gcc -c t.c -arch ppc
&lt;span style=&quot;color:#808080&quot;&gt; 2 &lt;/span&gt;$ gcc -c t.c -arch ppc64
&lt;span style=&quot;color:#808080&quot;&gt; 3 &lt;/span&gt;t.c:6: warning: &#039;transparent_union&#039; attribute ignored
&lt;span style=&quot;color:#808080&quot;&gt; 4 &lt;/span&gt;$ gcc -c t.c -arch i386 
&lt;span style=&quot;color:#808080&quot;&gt; 5 &lt;/span&gt;$ gcc -c t.c -arch x86_64&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
 
    </content:encoded>

    <pubDate>Sat, 15 Dec 2007 14:32:39 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/2-guid.html</guid>
    <category>gcc</category>
<category>mac os x</category>
<category>powerpc</category>

</item>
<item>
    <title>Welcome to the Portability Blog!</title>
    <link>http://portabilityblog.com/blog/archives/1-Welcome-to-the-Portability-Blog!.html</link>
            <category>Miscellany</category>
    
    <comments>http://portabilityblog.com/blog/archives/1-Welcome-to-the-Portability-Blog!.html#comments</comments>
    <wfw:comment>http://portabilityblog.com/blog/wfwcomment.php?cid=1</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://portabilityblog.com/blog/rss.php?version=2.0&amp;type=comments&amp;cid=1</wfw:commentRss>
    

    <author>nospam@example.com (Daniel Fischer)</author>
    <content:encoded>
    Hello there. I&#039;m Danny, and also, going to use this blog to post stories about all the minor and not so minor annoyances in building software on different platforms from the same code base. If you think that doesn&#039;t sound like a lot of fun, you&#039;re probably not the type of person that enjoys digging into the build process and stepping through each individual stage between &quot;source file&quot; and &quot;binary&quot;. I&#039;m not saying that I enjoy it myself, but it&#039;s part of what I do for a living. And maybe I do actually enjoy it a little, too &lt;img src=&quot;http://portabilityblog.com/blog/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Sat, 15 Dec 2007 14:26:23 +0100</pubDate>
    <guid isPermaLink="false">http://portabilityblog.com/blog/archives/1-guid.html</guid>
    
</item>

</channel>
</rss>