From: Jarkko Hietaniemi Date: Mon, 10 Jul 2006 15:41:10 +0000 (+0300) Subject: perlhack: more portability musings X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0bec6c03caec93aa207fcfeff506a7c46c7019e9;p=p5sagit%2Fp5-mst-13.2.git perlhack: more portability musings Message-ID: <44B24AE6.6030708@iki.fi> p4raw-id: //depot/perl@28527 --- diff --git a/pod/perlhack.pod b/pod/perlhack.pod index 28cea1d..5a7263c 100644 --- a/pod/perlhack.pod +++ b/pod/perlhack.pod @@ -2369,7 +2369,7 @@ Not compiling with threading 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_ ...); @@ -2387,7 +2387,7 @@ for further discussion about context. 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 * @@ -2424,9 +2424,14 @@ in L. 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 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 @@ -2450,10 +2455,12 @@ INT2PTR(), and NUM2PTR().) =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 * @@ -2464,7 +2471,11 @@ are 64 bits, and while we are out to shock you, even platforms where 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 guaranteed to be I +32 bits, they are I 32 bits, nor are they guaranteed to +be B or B. If you really explicitly need 64-bit variables, +use I64 and U64, but only if guarded by HAS_QUAD. =item * @@ -2487,13 +2498,27 @@ or maybe use temporary variables. =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 * @@ -2505,7 +2530,16 @@ Mixing declarations and code 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 * @@ -2519,9 +2553,9 @@ Mixing signed char pointers with unsigned char pointers 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 * @@ -2535,10 +2569,26 @@ Pre-ANSI semantics for that was equivalent to 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 @@ -2568,8 +2618,10 @@ the strlcpy/strlcat implementation of INN. 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