Thursday, January 25, 2001
BSD headers—Just Say No!
I got called to help a friend compile a program. He's still learning C and the program he was compiling was throwing up the following error:
gcc -O2 -DHAVE_CONFIG_H -D_GNU_SOURCE -I. -Iprotos -c action.c action.c: In function `action_command': action.c:51: void value not ignored as it ought to be action.c: In function `substitute_vars': action.c:138: void value not ignored as it ought to be action.c:143: void value not ignored as it ought to be action.c:163: void value not ignored as it ought to be action.c: In function `check_one_action': action.c:245: void value not ignored as it ought to be make: *** [action.o] Error 1
It was failing on the strcpy()
and strncpy()
functions.
It was apparent to me that the program was using an improper definition of
the functions—the problem was to figure out where it was pulling the
defintions in from. Easy enough to generate what the preprocessor was
feeding into the compiler (with gcc
using the -E
option
and sending the output to a file).
The original lines:
if (*!ptr) strcpy(pr, "5"); /* defaults priority to 5 if no value given */
And the preprocessor was spitting out:
if(!*pr) (__extension__ (__builtin_constant_p ( "5" ) ? (((size_t)(const void *)(( "5" ) + 1) - (size_t)(const void *)( "5" ) == 1) && strlen ( "5" ) + 1 <= 8 ? __strcpy_small ( pr , __extension__ (((__const unsigned char *) (__const char *) ( "5" ))[ 0 + 1] << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 0 ]) , __extension__ (((__const unsigned char *) (__const char *) ( "5" ))[ 4 + 1] << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 4 ]) , __extension__ (((((__const unsigned char *) (__const char *) ( "5" ))[ 0 + 3] << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 0 + 2]) << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 0 + 1]) << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 0 ]) , __extension__ (((((__const unsigned char *) (__const char *) ( "5" ))[ 4 + 3] << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 4 + 2]) << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 4 + 1]) << 8 | ((__const unsigned char *) (__const char *) ( "5" ))[ 4 ]) , strlen ( "5" ) + 1) : (char *) bcopy( "5" , pr , strlen ( "5" ) + 1 ) ) : strcpy ( pr , "5" ))) ;
Oh my. Mind you, that was one line and no attempt to even comprehend that is being made (in fact, the breaks are just where hey happened when I copied the text in).
Checking the file futher, I can see it's including strings.h
which
is not part of the ANSI standard. In fact, it's an old BSDism,
which shouldn't be used anymore. Some mucking about with the header file
spit out by configure
got the compile to work.
So much for using configure.