Also study L<perlport> carefully to avoid any bad assumptions
about the operating system, filesystem, and so forth.
-You may once in a while try a "make miniperl" to see whether
-we can compile Perl with just the bare minimum of interfaces.
+You may once in a while try a "make miniperl" to see whether we
+can still compile Perl with just the bare minimum of interfaces.
Do not assume an operating system indicates a certain compiler.
shorts are 64 bits. This is all legal according to the C standard.
(In other words, "long long" is not a portable way to specify 64 bits,
and "long long" is not even guaranteed to be any wider than "long".)
-Use the definitions IV, UV, IVSIZE, I32SIZE, and so forth. Avoid
-things like I32 because they are B<not> guaranteed to be I<exactly>
-32 bits, they are I<at least> 32 bits, nor are they guaranteed to
-be B<int> or B<long>. If you really explicitly need 64-bit variables,
-use I64 and U64, but only if guarded by HAS_QUAD.
+
+Instead, use the definitions IV, UV, IVSIZE, I32SIZE, and so forth.
+Avoid things like I32 because they are B<not> guaranteed to be
+I<exactly> 32 bits, they are I<at least> 32 bits, nor are they
+guaranteed to be B<int> or B<long>. If you really explicitly need
+64-bit variables, use I64 and U64, but only if guarded by HAS_QUAD.
=item *
That is C99 or C++. Some C compilers allow that, but you shouldn't.
+The gcc option C<-Wdeclaration-after-statements> scans for such problems
+(by default on starting from Perl 5.9.4).
+
=item *
Introducing variables inside for()
While this is legal practice, it is certainly dubious, and downright
fatal in at least one platform: for example VMS cc considers this a
-fatal error. One cause for people often making this mistake is that a
-"naked char" and therefore dereferencing a "naked char pointer" have
+fatal error. One cause for people often making this mistake is that
+a "naked char" and therefore dereferencing a "naked char pointer" have
an undefined signedness: it depends on the compiler and the platform
-whether the result is signed or unsigned.
+whether the result is signed or unsigned. For this very same reason
+using a 'char' as an array index is bad.
=item *
which is probably not what you were expecting. Unfortunately at least
one reasonably common and modern C compiler does "real backward
-compatibility here", in AIX that is what still happens even though the
+compatibility" here, in AIX that is what still happens even though the
rest of the AIX compiler is very happily C89.
=item *
printf("who = %"Uid_t_f"\n", who);
+Or you can try casting to a "wide enough" type:
+
+ printf("i = %"IVdf"\n", (IV)something_very_small_and_signed);
+
+Also remember that the C<%p> format really does require a void pointer:
+
+ U8* p = ...;
+ printf("p = %p\n", (void*)p);
+
The gcc option C<-Wformat> scans for such problems.
=item *
Blindly using variadic macros
-gcc has had them for a while with its own syntax, and C99
-brought them with a standardized syntax. Don't use the former,
-and use the latter only if the HAS_C99_VARIADIC_MACROS.
+gcc has had them for a while with its own syntax, and C99 brought
+them with a standardized syntax. Don't use the former, and use
+the latter only if the HAS_C99_VARIADIC_MACROS is defined.
=item *
=item *
+Using gcc brace groups
+
+ val = ({...;...;...});
+
+While a nice extension, it's not portable.
+
+=item *
+
+Binding together several statements
+
+Use the macros STMT_START and STMT_END.
+
+ STMT_START {
+ ...
+ } STMT_END
+
+=item *
+
Testing for operating systems or versions when should be testing for features
#ifdef __FOONIX__