* faq-programming.xml (faq.programming.64bitporting): Extend entry.
(faq.programming.64bitporting-fail): New entry. (faq.programming.64bitporting-cygwin64): New entry.
This commit is contained in:
		| @@ -1,3 +1,9 @@ | |||||||
|  | 2013-04-24  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* faq-programming.xml (faq.programming.64bitporting): Extend entry. | ||||||
|  | 	(faq.programming.64bitporting-fail): New entry. | ||||||
|  | 	(faq.programming.64bitporting-cygwin64): New entry. | ||||||
|  |  | ||||||
| 2013-04-24  Corinna Vinschen  <corinna@vinschen.de> | 2013-04-24  Corinna Vinschen  <corinna@vinschen.de> | ||||||
| 	    Christian Franke  <Christian.Franke@t-online.de> | 	    Christian Franke  <Christian.Franke@t-online.de> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -75,8 +75,8 @@ sizeof(void*)       4        8        8 | |||||||
| <para>This difference can result in interesting problems, especially when | <para>This difference can result in interesting problems, especially when | ||||||
| using Win32 functions, especially when using pointers to Windows | using Win32 functions, especially when using pointers to Windows | ||||||
| datatypes like LONG, ULONG, DWORD.  Given that Windows is LLP64, all of | datatypes like LONG, ULONG, DWORD.  Given that Windows is LLP64, all of | ||||||
| the aforementioned types are 4 byte in size, while `long' on 64 bit Cygwin | the aforementioned types are 4 byte in size, on 32 as well as on 64 bit | ||||||
| is 8 bytes.</para> | Windows, while `long' on 64 bit Cygwin is 8 bytes.</para> | ||||||
|  |  | ||||||
| <para>Take the example ReadFile:</para> | <para>Take the example ReadFile:</para> | ||||||
|  |  | ||||||
| @@ -142,11 +142,17 @@ which has no immediate connection to the actual bug. | |||||||
|  |  | ||||||
| <screen> | <screen> | ||||||
|     void *ptr; |     void *ptr; | ||||||
|     printf ("Pointer value is %x\n", (int) ptr); |     printf ("Pointer value is %x\n", ptr); | ||||||
| </screen> | </screen> | ||||||
|  |  | ||||||
| The value printed by printf is missing the upper 4 bytes, so the printed | %x denotes an int argument.  The value printed by printf is a 4 byte value, | ||||||
| value is very likely wrong. | so on x86_64 the printed pointer value is missing its upper 4 bytes; the output | ||||||
|  | is very likely wrong.  Use %p instead, which portable across architectures: | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  |     void *ptr; | ||||||
|  |     printf ("Pointer value is %p\n", ptr); | ||||||
|  | </screen> | ||||||
| </para></listitem> | </para></listitem> | ||||||
|  |  | ||||||
| <listitem><para> | <listitem><para> | ||||||
| @@ -155,7 +161,7 @@ pointer arithmetic.  Don't cast pointers to int, don't cast pointer | |||||||
| differences to int, and don't store pointer differences in an int type. | differences to int, and don't store pointer differences in an int type. | ||||||
| Use the types <literal>intptr_t</literal>, <literal>uintptr_t</literal> | Use the types <literal>intptr_t</literal>, <literal>uintptr_t</literal> | ||||||
| and <literal>ptrdiff_t</literal> instead, they are designed for performing | and <literal>ptrdiff_t</literal> instead, they are designed for performing | ||||||
| pointer arithmetic. | architecture-independent pointer arithmetic. | ||||||
| </para></listitem> | </para></listitem> | ||||||
|  |  | ||||||
| <listitem><para> | <listitem><para> | ||||||
| @@ -181,9 +187,23 @@ string pointer given to printf is missing the upper 4 bytes. | |||||||
|  |  | ||||||
| <listitem><para> | <listitem><para> | ||||||
| <emphasis>Don't</emphasis> use C base types together with Win32 functions. | <emphasis>Don't</emphasis> use C base types together with Win32 functions. | ||||||
| Keep in mind that DWORD, LONG, ULONG are *not* the same as long and unsigned | Keep in mind that DWORD, LONG, ULONG are <emphasis>not</emphasis> the same | ||||||
| long.  Try to use only Win32 datatypes in conjunction with Win32 API function | as long and unsigned long.  Try to use only Win32 datatypes in conjunction | ||||||
| calls to avoid type problems.  See the above ReadFile example. | with Win32 API function calls to avoid type problems.  See the above | ||||||
|  | ReadFile example.  Windows functions in printf calls should be treated | ||||||
|  | carefully as well.  This code is common for 32 bit code, but probably prints | ||||||
|  | the wrong value on 64 bit: | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  |     printf ("Error message is: %lu\n", GetLastError ()); | ||||||
|  | </screen> | ||||||
|  |  | ||||||
|  | Using gcc's -Wformat option would warn about this.  Casting to the requested | ||||||
|  | base type helps in this case: | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  |     printf ("Error message is: %lu\n", (unsigned long) GetLastError ()); | ||||||
|  | </screen> | ||||||
| </para></listitem> | </para></listitem> | ||||||
|  |  | ||||||
| <listitem><para> | <listitem><para> | ||||||
| @@ -204,6 +224,111 @@ long but rather unsigned int on 64 bit. | |||||||
|  |  | ||||||
| </answer></qandaentry> | </answer></qandaentry> | ||||||
|  |  | ||||||
|  | <qandaentry id="faq.programming.64bitporting-fail"> | ||||||
|  | <question><para>My project doesn't build at all on 64 bit Cygwin.  What's up?</para></question> | ||||||
|  | <answer> | ||||||
|  |  | ||||||
|  | <para>Typically reasons for that are:</para> | ||||||
|  |  | ||||||
|  | <itemizedlist mark="bullet"> | ||||||
|  |  | ||||||
|  | <listitem><para><literal>__CYGWIN32__</literal> is not defined in the | ||||||
|  | 64 bit toolchain.  This may hit a few projects which are around since before | ||||||
|  | Y2K.  Check your project for occurences of <literal>__CYGWIN32__</literal> | ||||||
|  | and change them to <literal>__CYGWIN__</literal>, which is defined in the | ||||||
|  | Cygwin toolchain since 1998, to get the same Cygwin-specific code changes done. | ||||||
|  | </para></listitem> | ||||||
|  |  | ||||||
|  | <listitem><para>The project maintainers took it for granted that Cygwin is | ||||||
|  | running only on i686 CPUs and the code is making this assumption blindly. | ||||||
|  | You have to check the code for such assumptions and fix them. | ||||||
|  | </para></listitem> | ||||||
|  |  | ||||||
|  | <listitem><para>The project is using autotools, the | ||||||
|  | <filename>config.sub</filename> and <filename>config.guess</filename> files | ||||||
|  | are hopelessly outdated and don't recognize | ||||||
|  | <literal>x86_64-{pc,unknown}-cygwin</literal> as valid target.  Update the | ||||||
|  | project configury (cygport will do this by default) and try again. | ||||||
|  | </para></listitem> | ||||||
|  |  | ||||||
|  | <listitem><para>The project uses Windows functions on Cygwin and it's suffering | ||||||
|  | from the problems described in the preceeding FAQ entry. | ||||||
|  | </para></listitem> | ||||||
|  |  | ||||||
|  | </itemizedlist> | ||||||
|  |  | ||||||
|  | <para>In all of this cases, please make sure to fix that upstream, or send | ||||||
|  | your patches to the upstream maintainers, so the problems get fixed for the | ||||||
|  | future.</para> | ||||||
|  |  | ||||||
|  | </answer></qandaentry> | ||||||
|  |  | ||||||
|  | <qandaentry id="faq.programming.64bitporting-cygwin64"> | ||||||
|  | <question><para>Why is __CYGWIN64__ not defined for 64 bit?</para></question> | ||||||
|  | <answer> | ||||||
|  |  | ||||||
|  | <para>There is no <literal>__CYGWIN64__</literal> because we would like to | ||||||
|  | have a unified way to handle Cygwin code in portable projects.  Using | ||||||
|  | <literal>__CYGWIN32__</literal> and <literal>__CYGWIN64__</literal> only | ||||||
|  | complicates the code for no good reason.  Along the same lines you won't | ||||||
|  | find predefined macros <literal>__linux32__</literal> and | ||||||
|  | <literal>__linux64__</literal> on Linux.</para> | ||||||
|  |  | ||||||
|  | <para>If you really have to differ between 32 and 64 bit in some way, you have | ||||||
|  | three choices.</para> | ||||||
|  |  | ||||||
|  | <itemizedlist mark="bullet"> | ||||||
|  |  | ||||||
|  | <listitem><para>If your code depends on the CPU architecture, use the | ||||||
|  | predefined compiler definition for the architecture, like this:</para> | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  | #ifdef __CYGWIN__ | ||||||
|  | # ifdef __x86_64__	/* Alternatively __x86_64, __amd64__, __amd64 */ | ||||||
|  |     /* Code specific for AMD64 CPU */ | ||||||
|  | # elif __X86__ | ||||||
|  |     /* Code specific for ix86 CPUs */ | ||||||
|  | # else | ||||||
|  | #   error Unsupported Architecture | ||||||
|  | # endif | ||||||
|  | #endif | ||||||
|  | </screen></listitem> | ||||||
|  |  | ||||||
|  | <listitem><para>If your code depends on differences in the data model, you | ||||||
|  | should consider to use the <literal>__LP64__</literal> definition | ||||||
|  | instead:</para> | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  | #ifdef __CYGWIN__ | ||||||
|  | # ifdef __LP64__	/* Alternatively _LP64 */ | ||||||
|  |     /* Code specific for 64 bit CPUs */ | ||||||
|  | # else | ||||||
|  |     /* Code specific for 32 bit CPUs */ | ||||||
|  | # endif | ||||||
|  | #endif | ||||||
|  | </screen></listitem> | ||||||
|  |  | ||||||
|  | <listitem><para>If your code uses Windows functions, and some of the | ||||||
|  | functionality is 64 bit Windows-specific, use <literal>_WIN64</literal>, | ||||||
|  | which is defined on 64 bit Cygwin, as soon as you include | ||||||
|  | <filename>windows.h</filename>.  This should only be used in the most | ||||||
|  | desperate of occasions, though, and <emphasis>only</emphasis> if it's | ||||||
|  | really about a difference in Windows API functionality!</para> | ||||||
|  |  | ||||||
|  | <screen> | ||||||
|  | #ifdef __CYGWIN__ | ||||||
|  | # ifdef _WIN64 | ||||||
|  |     /* Code specific for 64 bit Windows */ | ||||||
|  | # else | ||||||
|  |     /* Code specific for 32 bit Windows */ | ||||||
|  | # endif | ||||||
|  | #endif | ||||||
|  | </screen></listitem> | ||||||
|  |  | ||||||
|  | </itemizedlist> | ||||||
|  |  | ||||||
|  | </answer></qandaentry> | ||||||
|  |  | ||||||
| <qandaentry id="faq.programming.glibc"> | <qandaentry id="faq.programming.glibc"> | ||||||
| <question><para>Where is glibc?</para></question> | <question><para>Where is glibc?</para></question> | ||||||
| <answer> | <answer> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user