C++ requires that function declarations have prototyped parameter lists, but Classic C won't accept prototypes. Code that compiles as both C++ and Classic C must sense which language is compiling the code, and turn the prototypes on and off accordingly. C++ compilers predefine the macro _cplusplus, so
#ifdef _cplusplusdetermines the current language.The simplest way to write a header that is both Classic C and C++ is to write all the function declarations twice - once with an empty parameter list and once with a prototyped parameter list. Select the appropriate declarations by testing _cplusplus, as in
#ifdef __cplusplus double foo(char *, int); int bar(char *); #else double foo( ); int bar( ); #endifIf you would also like to use prototypes when compiling with Standard C, add a test for the predefined macro _STDC_. You can write the test as
#if defined_cplusplus || \ defined __STDC__but Classic C compilers might not understand the defined operator. Write the test as
#ifdef __cplusplus #define PROTOTYPES #else #ifdef __STDC__ #define PROTOTYPES #endif #endifTo avoid writing each function declaration twice, make each parameter list conditional. Define a macro PROTO as
#ifdef PROTOTYPES #define PROTO(x) x #else #define PROTO(x) ( ) #endifThen write the function declarations as
double foo PROTO((char *, int)); int bar PROTO((char *));The extra set of parentheses around each parameter list transforms the comma-separated list of tokens into a single macro argument. Thus, if prototypes are available, then
PROTO((char *, int))expands to
(char *, int)Otherwise, it expands to just ( ).C++ wants you to replace old-style function definition headings like
double foo(s, n) char *s; int n; { ...with prototype definitions like
double foo(char *s, int n) { ...But Classic C won't accept the prototypes. To make the replacement conditional, write the function definition as
#if PROTOTYPES double foo(char *s, int n) #else double foo(s, n) char *s; int n; #endif { ...This heading is admittedly hard to read. Since C++ only issues a warning (not an error) for old-style headings, you may prefer to just live with the warnings.