This is a live mirror of the Perl 5 development currently hosted at
For Perl, assume C89 prototypes exist
authorAaron Crane <>
Thu, 12 Oct 2017 16:40:23 +0000 (18:40 +0200)
committerAaron Crane <>
Sat, 21 Oct 2017 15:45:08 +0000 (16:45 +0100)
Perl now relies on C89, including prototypes. However, it must continue to
define CAN_PROTOTYPE for the benefit of XS modules. So the Perl-specific
modified version of U/modified/prototype.U is now a stub that probes for
nothing, but still overrides the dist/ version of prototype.U (which would
otherwise find the remaining CAN_PROTOTYPE occurrences in the core and
include the probe anyway).

In addition, the Protochk unit itself looks at CAN_PROTOTYPE, and is used by
many other units. So create a modified version which doesn't do that.

U/modified/Protochk.U [new file with mode: 0644]

diff --git a/U/modified/Protochk.U b/U/modified/Protochk.U
new file mode 100644 (file)
index 0000000..d6f6e6c
--- /dev/null
@@ -0,0 +1,108 @@
+?RCS: $Id: Protochk.U,v $
+?RCS: Copyright (c) 1998 Andy Dougherty
+?RCS: You may distribute under the terms of either the GNU General Public
+?RCS: License or the Artistic License, as specified in the README file.
+?X:    This unit generates a ./protochk script that is used internally
+?X:    by Configure to check if this system will accept a particular
+?X:    prototype.
+?X:    To use it, say something like:
+?X:    hdrs="$define sys/types.h
+?X:            $i_systime sys/time.h
+?X:            $i_sysselct sys/select.h
+?X:            $d_socket sys/socket.h"
+?X:    $xxx='fd_set *'
+?X:    try='extern int select _((int, $xxx, $xxx, $xxx, struct timeval *'));'
+?X:    if ./protochk "$try" $hdrs; then
+?X:            echo "Your system accepts $xxx for the arguments to select."
+?X:    fi
+?X:  (Of course select is harder, since the first arg can be int,
+?X:    size_t, or unsigned long, and the last arg may or may not have a
+?X:    'const' before the 'struct timeval' :-(.  Also SunOS 4.1.3 doesn't
+?X:    provide a select prototype so the compiler accepts anything :-).
+?X:    The C compiler on QNX warns about invalid pointer types, but
+?X:    still exits with a 0 exit status, so it's not much help here.
+?X:    (It does correctly detect incorrect non-pointer arguments).
+?X:    Still, since QNX is a POSIX-ish system, just make your first
+?X:    a POSIX-ish one, and QNX will probably accept it.
+?X:    For determining argument types, your compiler must support
+?X:    prototypes, and the header files must use them.  Determining
+?X:    return types, however, is easier.  Just give an ridiculous
+?X:    return type, something like
+?X:    ./protochk 'extern int atof _((void));' $i_stdlib stdlib.h
+?X:    that should surely fail if atof() is defined in <stdlib.h>
+?X:    There is also an 'escape' hatch built in.  If you have a pair
+?X:    of args   'literal 'stuff' then 'stuff' gets included literally
+?X:    into the test program.  This could be useful for doing something
+?X:    like
+?X:    hdrs="$define stdio.h
+?X:            $define sys/types.h"
+?X:    ./protochk 'extern int fsetpos(FILE *, Fpos_t);' $args \
+?X:                    'literal' '#define Fpos_t long long'
+?X:    but you have to be really careful about the spaces in "literal".
+?X:            Andy Dougherty   Feb. 1998
+?MAKE:Protochk: cat rm_try startsh eunicefix +cc +optimize +ccflags \
+       i_pthread usethreads
+?MAKE: -pick add $@ %<
+?X: Comfort metalint.  All these are actually used in the protochk script.
+?T:foo status pthread_h_done
+?LINT: change cc optimize ccflags define rm_try
+?LINT: extern pthread_h_first
+?LINT: change pthread_h_first
+?LINT: change usethreads
+?LINT: change i_pthread
+: define a function to check prototypes
+$cat > protochk <<EOSH
+$cat >> protochk <<'EOSH'
+while test $# -ge 2; do
+       case "$1" in
+               $define) echo "#include <$2>" >> try.c ;;
+               literal) echo "$2" >> try.c ;;
+       esac
+    # Extra magic for the benefit of systems that need pthread.h
+    # to be included early to correctly detect threadsafe functions.
+    # Such functions must guarantee themselves, though, that the usethreads
+    # and i_pthread have been defined, before calling protochk.
+    if test "$usethreads" = "$define" -a "$i_pthread" = "$define" -a "$pthread_h_first" = "$define" -a "$pthread_h_done" = ""; then
+       echo "#include <pthread.h>" >> try.c
+       pthread_h_done=yes
+    fi
+    shift 2
+cat >> try.c <<'EOCP'
+#define        _(args) args
+echo "$foo" >> try.c
+?X: Just so we have something to compile.
+echo 'int no_real_function_has_this_name _((void)) { return 0; }' >> try.c
+$cc $optimize $ccflags -c try.c > /dev/null 2>&1
+exit $status
+chmod +x protochk
+$eunicefix protochk
index 12eb7eb..ca3df2f 100644 (file)
 ?RCS: Revision 3.0  1993/08/18  12:09:36  ram
 ?RCS: Baseline for dist 3.0 netwide release.
-?MAKE:prototype: Myread Oldconfig cat +cc +ccflags rm Setvar i_stdlib
-?MAKE: -pick add $@ %<
+?MAKE:prototype: Nothing
 ?S:    This variable holds the eventual value of CAN_PROTOTYPE, which
 ?S:    indicates the C compiler can handle function prototypes.
-?C:    If defined, this macro indicates that the C compiler can handle
-?C:    function prototypes.
-?C:    This macro is used to specify the ... in function prototypes which
-?C:    have arbitrary additional arguments.
-?C:    This macro is used to separate arguments in the declared argument list.
-?C:    This macro is used to declare "private" (static) functions.
-?C:    It takes three arguments: the function type and name, a parenthesized
-?C:    traditional (comma separated) argument list, and the declared argument
-?C:    list (in which arguments are separated with NXT_ARG, and additional
-?C:    arbitrary arguments are specified with DOTS).  For example:
-?C:            P_FUNC(int foo, (bar, baz), int bar NXT_ARG char *baz[])
-?C:    This macro is used to declare "private" (static) functions that have
-?C:    no arguments.  The macro takes one argument: the function type and name.
-?C:    For example:
-?C:            P_FUNC_VOID(int subr)
-?C:    This macro is used to declare "public" (non-static) functions.
-?C:    It takes three arguments: the function type and name, a parenthesized
-?C:    traditional (comma separated) argument list, and the declared argument
-?C:    list (in which arguments are separated with NXT_ARG, and additional
-?C:    arbitrary arguments are specified with DOTS).  For example:
-?C:            V_FUNC(int main, (argc, argv), int argc NXT_ARG char *argv[])
-?C:    This macro is used to declare "public" (non-static) functions that have
-?C:    no arguments.  The macro takes one argument: the function type and name.
-?C:    For example:
-?C:            V_FUNC_VOID(int fork)
-?C:_ (P):
-?C:    This macro is used to declare function parameters for folks who want
-?C:    to make declarations with prototypes using a different style than
-?C:    the above macros.  Use double parentheses.  For example:
-?C:            int main _((int argc, char *argv[]));
-?H:?%<:#$prototype     CAN_PROTOTYPE   /**/
-?H:?_:#ifdef CAN_PROTOTYPE
-?H:?NXT_ARG:#define    NXT_ARG ,
-?H:?DOTS:#define       DOTS , ...
-?H:?V_FUNC:#define     V_FUNC(name, arglist, args)name(args)
-?H:?P_FUNC:#define     P_FUNC(name, arglist, args)static name(args)
-?H:?V_FUNC_VOID:#define        V_FUNC_VOID(name)name(void)
-?H:?P_FUNC_VOID:#define        P_FUNC_VOID(name)static name(void)
-?H:?_:#define  _(args) args
-?H:?NXT_ARG:#define    NXT_ARG ;
-?H:?DOTS:#define       DOTS
-?H:?V_FUNC:#define     V_FUNC(name, arglist, args)name arglist args;
-?H:?P_FUNC:#define     P_FUNC(name, arglist, args)static name arglist args;
-?H:?V_FUNC_VOID:#define        V_FUNC_VOID(name)name()
-?H:?P_FUNC_VOID:#define        P_FUNC_VOID(name)static name()
-?H:?_:#define  _(args) ()
-?LINT:set prototype
-: Cruising for prototypes
-echo " "
-echo "Checking out function prototypes..." >&4
-$cat >prototype.c <<EOCP
-#$i_stdlib I_STDLIB
-#ifdef I_STDLIB
-#include <stdlib.h>
-int main(int argc, char *argv[]) {
-       exit(0);}
-if $cc $ccflags -c prototype.c >prototype.out 2>&1 ; then
-       echo "Your C compiler appears to support function prototypes."
-       val="$define"
-       echo "Your C compiler doesn't seem to understand function prototypes."
-       val="$undef"
-set prototype
-eval $setvar
-$rm -f prototype*
+: stub, never used