Compiling with threading (-Duseithreads) completely rewrites
the function prototypes of Perl. You better try your changes
-with that. Related to this is the difference between "Perl_"-less
+with that. Related to this is the difference between "Perl_-less"
and "Perl_-ly" APIs, for example:
Perl_sv_setiv(aTHX_ ...);
Not compiling with -DDEBUGGING
The DEBUGGING define exposes more code to the compiler,
-therefore more ways for things to go wrong.
+therefore more ways for things to go wrong. You should try it.
=item *
The following are common causes of compilation and/or execution
failures, not common to Perl as such. The C FAQ is good bedtime
-reading. Please test your changes with as many C compilers as
-possible -- we will, anyway, and it's nice to save oneself from
-public embarrassment.
+reading. Please test your changes with as many C compilers and
+platforms as possible -- we will, anyway, and it's nice to save
+oneself from public embarrassment.
+
+Also study L<perlport> carefully to avoid any bad assumptions
+about the operating system, filesystem, and so forth.
+
+Do not assume an operating system indicates a certain compiler.
=over 4
=item *
+Casting between data function pointers and data pointers
+
Technically speaking casting between function pointers and data
pointers is unportable and undefined, but practically speaking
it seems to work, but you should use the FPTR2DPTR() and DPTR2FPTR()
-macros.
+macros. Sometimes you can also play games with unions.
=item *
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 definitions like IVSIZE, I32SIZE, and so forth.
+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 *
=item *
+Mixing #define and #ifdef
+
+ #define BURGLE(x) ... \
+ #ifdef BURGLE_OLD_STYLE
+ ... do it the old way ... \
+ #else
+ ... do it the new way ... \
+ #endif
+
+You cannot portably "stack" cpp directives. For example in the
+above you need two separate #defines, one in each #ifdef branch.
+
+=item *
+
Using //-comments
// This function bamfoodles the zorklator.
That is C99 or C++. Perl is C89. Using the //-comments is silently
-allowed by many C compilers but cranking up the ANSI strictness (which
-we like to do) causes the compilation to fail.
+allowed by many C compilers but cranking up the ANSI C89 strictness
+(which we like to do) causes the compilation to fail.
=item *
set_zorkmids(n);
int q = 4;
-That is C99 or C++. Some compilers allow that, but you shouldn't.
+That is C99 or C++. Some C compilers allow that, but you shouldn't.
+
+=item *
+
+Introducing variables inside for()
+
+ for(int i = ...; ...; ...)
+
+That is C99 or C++. While it would indeed be awfully nice to have that
+also in C89, to limit the scope of the loop variable, alas, we cannot.
=item *
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 deferencing a "naked char pointer" have an
-undefined sign: it depends on the compilers and the platform whether
-the result is signed or unsigned.
+"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.
=item *
printf("10umber = %d\10");
-which is probably not what you were expecting. Unfortunately at
-least one C compiler does real backward compatibility here, in AIX
-that is what still happens even though the rest of the AIX compiler
-is very happily C89.
+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
+rest of the AIX compiler is very happily C89.
+
+=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.
+
+=item *
+
+Blindly passing va_list
+
+Not all platforms support passing va_list to further varargs (stdarg)
+functions. The right thing to do is to copy the va_list using the
+Perl_va_copy() if the NEED_VA_COPY is defined.
=back
Do not use sprintf() or vsprintf()
-Use my_snprintf() and my_vnsprintf() instead, which will try to use
-snprintf() and vsnprintf() if those safer APIs are available.
+If you really want just plain byte strings, use my_snprintf()
+and my_vnsprintf() instead, which will try to use snprintf() and
+vsnprintf() if those safer APIs are available. If you want something
+fancier than a plain byte string, use SVs and Perl_sv_catpvf().
=back