* 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:
parent
21470a3ca9
commit
77dcee573c
|
@ -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>
|
||||
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
|
||||
using Win32 functions, especially when using pointers to Windows
|
||||
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
|
||||
is 8 bytes.</para>
|
||||
the aforementioned types are 4 byte in size, on 32 as well as on 64 bit
|
||||
Windows, while `long' on 64 bit Cygwin is 8 bytes.</para>
|
||||
|
||||
<para>Take the example ReadFile:</para>
|
||||
|
||||
|
@ -142,11 +142,17 @@ which has no immediate connection to the actual bug.
|
|||
|
||||
<screen>
|
||||
void *ptr;
|
||||
printf ("Pointer value is %x\n", (int) ptr);
|
||||
printf ("Pointer value is %x\n", ptr);
|
||||
</screen>
|
||||
|
||||
The value printed by printf is missing the upper 4 bytes, so the printed
|
||||
value is very likely wrong.
|
||||
%x denotes an int argument. The value printed by printf is a 4 byte value,
|
||||
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>
|
||||
|
||||
<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.
|
||||
Use the types <literal>intptr_t</literal>, <literal>uintptr_t</literal>
|
||||
and <literal>ptrdiff_t</literal> instead, they are designed for performing
|
||||
pointer arithmetic.
|
||||
architecture-independent pointer arithmetic.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
|
@ -181,9 +187,23 @@ string pointer given to printf is missing the upper 4 bytes.
|
|||
|
||||
<listitem><para>
|
||||
<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
|
||||
long. Try to use only Win32 datatypes in conjunction with Win32 API function
|
||||
calls to avoid type problems. See the above ReadFile example.
|
||||
Keep in mind that DWORD, LONG, ULONG are <emphasis>not</emphasis> the same
|
||||
as long and unsigned long. Try to use only Win32 datatypes in conjunction
|
||||
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>
|
||||
|
||||
<listitem><para>
|
||||
|
@ -204,6 +224,111 @@ long but rather unsigned int on 64 bit.
|
|||
|
||||
</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">
|
||||
<question><para>Where is glibc?</para></question>
|
||||
<answer>
|
||||
|
|
Loading…
Reference in New Issue