Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-04-24 20:09:43 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-04-24 20:09:43 +0400
commit895ece012481194592198bf18a1b70790e784685 (patch)
tree47230b6fbab698f5b08a85213d380253b7bce1e7 /winsup/doc/faq-programming.xml
parent79b4d1beb0f99a1f20ed7f811d7ba52d77738372 (diff)
* faq-programming.xml (faq.programming.64bitporting): New FAQ entry.
(faq.programming.objective-c): Include gcc4. (faq.programming.make-execvp): Drop text discouraging usage of -j. (faq.programming.undeclared-functions): Drop entry. (faq.programming.x86-assembly): Ditto. (faq.programming.djgpp): Ditto.
Diffstat (limited to 'winsup/doc/faq-programming.xml')
-rw-r--r--winsup/doc/faq-programming.xml196
1 files changed, 155 insertions, 41 deletions
diff --git a/winsup/doc/faq-programming.xml b/winsup/doc/faq-programming.xml
index bfc27fac7..c46e05f18 100644
--- a/winsup/doc/faq-programming.xml
+++ b/winsup/doc/faq-programming.xml
@@ -48,6 +48,158 @@ package. Or compile with the <literal>-s</literal> option to gcc.
</para>
</answer></qandaentry>
+<qandaentry id="faq.programming.64bitporting">
+<question><para>What do I have to look out for when porting applications to 64 bit Cygwin?</para></question>
+<answer>
+
+<para>The Cygwin x86_64 toolchain is using the
+<ulink url="http://en.wikipedia.org/wiki/LLP64#64-bit_data_models">LP64</ulink>
+data model. That means, in contrast to Windows, which uses an
+<ulink url="http://en.wikipedia.org/wiki/LLP64#64-bit_data_models">LLP64</ulink>
+data model, sizeof(long) != sizeof(int), just as on Linux.</para>
+
+<para>For comparison:</para>
+
+<screen>
+ Cygwin Windows Cygwin
+ Linux x86_64 Linux
+ Windows x86_64
+ i686
+
+sizeof(int) 4 4 4
+sizeof(long) 4 4 8
+sizeof(size_t) 4 8 8
+sizeof(void*) 4 8 8
+</screen>
+
+<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>
+
+<para>Take the example ReadFile:</para>
+
+<screen>
+ ReadFile (HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
+</screen>
+
+<para>In the 32 bit Cygwin and Mingw environments, as well as in the 64 bit
+Mingw environment, it is no problem to substitute DWORD with unsigned
+long:</para>
+
+<screen>
+ unsigned long number_of_bytes_read;
+ [...]
+ ReadFile (fhdl, buf, buflen, &amp;number_of_bytes_read, NULL);
+</screen>
+
+<para>However, in 64 bit Cygwin, using LP64, number_of_bytes_read is 8 bytes
+in size. But since ReadFile expects a pointer to a 4 byte type, the function
+will only change the lower 4 bytes of number_of_bytes_read on return, while
+the content of the upper 4 bytes stays undefined.</para>
+
+<para>Here are a few <emphasis>donts</emphasis> which should help porting
+applications from the known ILP32 data model of 32 bit Cygwin, to the LP64
+data model of 64 bit Cygwin. Note that these are not Cygwin-only problems.
+Many Linux applications suffered the same somewhat liberal handling of
+datatypes when the AMD64 CPU was new.</para>
+
+<itemizedlist mark="bullet">
+
+<listitem><para>
+<emphasis>Don't</emphasis> mix up int and long in printf/scanf. This:
+
+<screen>
+ int i; long l;
+ printf ("%d %ld\n", l, i);
+</screen>
+
+may not print what you think it should.
+</para></listitem>
+
+<listitem><para>
+<emphasis>Don't</emphasis> mix int and long pointers.
+
+<screen>
+ long *long_ptr = (long *) &amp;my_int; /* Uh oh! */
+ *long_ptr = 42;
+</screen>
+
+The assignment will write 8 bytes to the address of my_int. Since my_int
+is only 4 bytes, <emphasis>something else</emphasis> gets randomly overwritten.
+Finding this kind of bug is very hard, because you will often see a problem
+which has no immediate connection to the actual bug.
+</para></listitem>
+
+<listitem><para>
+<emphasis>Don't</emphasis> mix int and pointers at all! This will
+<emphasis>not</emphasis> work as expected anymore:
+
+<screen>
+ void *ptr;
+ printf ("Pointer value is %x\n", (int) ptr);
+</screen>
+
+The value printed by printf is missing the upper 4 bytes, so the printed
+value is very likely wrong.
+</para></listitem>
+
+<listitem><para>
+Along the same lines <emphasis>don't</emphasis> use the type int in
+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.
+</para></listitem>
+
+<listitem><para>
+<emphasis>Don't</emphasis> make blind assumptions about the size of a POSIX
+type. For instance, <literal>time_t</literal> is 8 bytes on 64 bit Cygwin,
+while it is (still, at the time of writing this) 4 bytes on 32 bit Cygwin,
+since time_t is based on the type long.
+</para></listitem>
+
+<listitem><para>
+<emphasis>Don't</emphasis> use functions returning pointers without declaration.
+For instance
+
+<screen>
+ printf ("Error message is: %s\n", strerror (errno));
+</screen>
+
+This code will <emphasis>crash</emphasis>, unless you included
+<filename>string.h</filename>. The implicit rule in C is that an undeclared
+function is of type int. But int is 4 byte and pointers are 8 byte, so the
+string pointer given to printf is missing the upper 4 bytes.
+</para></listitem>
+
+<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.
+</para></listitem>
+
+<listitem><para>
+<emphasis>Don't</emphasis> mix Windows dataypes with POSIX type-specific
+MIN/MAX values.
+
+<screen>
+ unsigned long l_max = ULONG_MAX; /* That's right. */
+ ULONG w32_biggest = ULONG_MAX; /* Hey, wait! What? */
+ ULONG w32_biggest = UINT_MAX; /* Ok, but borderline. */
+</screen>
+
+Again, keep in mind that ULONG (or DWORD) is <emphasis>not</emphasis> unsigned
+long but rather unsigned int on 64 bit.
+</para></listitem>
+
+</itemizedlist>
+
+</answer></qandaentry>
+
<qandaentry id="faq.programming.glibc">
<question><para>Where is glibc?</para></question>
<answer>
@@ -62,7 +214,7 @@ would be difficult.
<question><para>Where is Objective C?</para></question>
<answer>
-<para>Support for compiling Objective C is available in the <literal>gcc4-objc</literal>
+<para>Support for compiling Objective C is available in the <literal>gcc{4}-objc</literal>
package; resulting binaries will depend on the <literal>libobjc2</literal>
package at runtime.
</para>
@@ -72,10 +224,8 @@ package at runtime.
<question><para>Why does my make fail on Cygwin with an execvp error? </para></question>
<answer>
-<para>First of all, if you are using <literal>make -j[N]</literal>, then stop. It doesn't
-work well. Also beware of using non-portable shell features in your
-Makefiles (see tips at <ulink
-url="http://cygwin.com/faq/faq.using.html#faq.using.shell-scripts" />).
+<para>Beware of using non-portable shell features in your Makefiles (see tips
+at <ulink url="http://cygwin.com/faq/faq.using.html#faq.using.shell-scripts" />).
</para>
<para>Errors of <literal>make: execvp: /bin/sh: Illegal Argument</literal> or
<literal>make: execvp: /bin/sh: Argument list too long</literal> are often
@@ -681,15 +831,6 @@ This is right <literal>gcc hello.cc -lstdc++</literal>.
use <literal>struct stat</literal>. It's 64 bit aware.</para>
</answer></qandaentry>
-<qandaentry id="faq.programming.undeclared-functions">
-<question><para>I use a function I know is in the API, but I still get a link error.</para></question>
-<answer>
-
-<para>The function probably isn't declared in the header files, or
-the UNICODE stuff for it isn't filled in.
-</para>
-</answer></qandaentry>
-
<qandaentry id="faq.programming.libc">
<question><para>Can you make DLLs that are linked against libc ?</para></question>
<answer>
@@ -758,17 +899,6 @@ data types, line numbers, local variables etc.
</para>
</answer></qandaentry>
-<qandaentry id="faq.programming.x86-assembly">
-<question><para>Where can I find info on x86 assembly?</para></question>
-<answer>
-
-<para>CPU reference manuals for Intel's current chips are available in
-downloadable PDF form on Intel's web site:
-</para>
-<para><ulink url="http://developer.intel.com/">http://developer.intel.com/</ulink>
-</para>
-</answer></qandaentry>
-
<qandaentry id="faq.programming.make-scripts">
<question><para>Shell scripts aren't running properly from my makefiles?</para></question>
<answer>
@@ -848,19 +978,3 @@ executable.</para></listitem>
linker flag.</para></listitem>
</orderedlist></listitem></orderedlist>
</answer></qandaentry>
-
-<qandaentry id="faq.programming.djgpp">
-<question><para>Why not use DJGPP ?</para></question>
-<answer>
-
-<para>DJGPP is a similar idea, but for DOS instead of Win32. DJGPP uses a
-"DOS extender" to provide a more reasonable operating interface for its
-applications. The Cygwin toolset doesn't have to do this since all of
-the applications are native WIN32. Applications compiled with the
-Cygwin tools can access the Win32 API functions, so you can write
-programs which use the Windows GUI.
-</para>
-<para>You can get more info on DJGPP by following
-<ulink url="http://www.delorie.com/">http://www.delorie.com/</ulink>.
-</para></answer></qandaentry>
-