Re: Spurious warning from gcc compiling kernel code

From: Norm Dresner (ndrez_at_att.net)
Date: 11/24/04


Date: Wed, 24 Nov 2004 21:19:30 GMT

Answering (at least partially) my own post below

"Norm Dresner" <ndrez@att.net> wrote in message
news:KL6pd.55407$7i4.8645@bgtnsc05-news.ops.worldnet.att.net...
> Consider this code fragment which might occur in almost any C-module.
>
> short asdf = 100;
> long poi = 22;
> int zxcv;
>
> zxcv = min( asdf , poi );
>
> There's nothing wrong with this code and there are millions of lines of
code
> just like it on hundreds of thousands of computers worldwide. And
compiling
> it in user-mode, it's fine. But compiling it as part of a kernel module,
I
> get a spurious diagnostic from the C-compiler. It seems that as long as
the
> two integer data types are different, I get a warning from the compiler
that
> says that
> warning: comparison of distinct pointer types lacks a cast
> But neither of the arguments in the min() function are pointers.
>
> Here's the command-line that produces the problem:
> #!/bin/tcsh
> gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs \
> -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundar
y=
> 2 \
> -march=i686 -DMODULE -fomit-frame-pointer -D__RTL__ \
> -I/usr/src/linux/include \
> -D_LOOSE_KERNEL_NAMES -O2 \
> -c blubber.c
>
> where the "source" of the problem seems to be the header files in
> /usr/src/linux/include
>
> Note that /usr/src/linux is not a link but the directory in which the
kernel
> source tree lives.
>
> Here's a "minimum" module that reproduces the problem:
>
> #include <linux/fs.h>
>
> int Function( char *buf , int channo , unsigned long count )
> {
> short ML = 150;
> long asdf = 10;
> short poi = 33;
> int zxcv;
> /********************************************************
> #define min(a,b) (((a)<(b))?(a):(b))
> blub.c:14 warning: comparison of distinct pointer types lacks a cast
> blub.c:15: warning: comparison of distinct pointer types lacks a cast
> ********************************************************/
> count = min( count , ML );
> zxcv = min( asdf , poi );
> return( count );
> }
>
>

The definitions in /usr/src/linux/include/linux/kernel.h are
        #define min(x,y) ({ \
             const typeof(x) _x = (x); \
              const typeof(y) _y = (y); \
             (void) (&_x == &_y); \
             _x < _y ? _x : _y; })

        #define max(x,y) ({ \
             const typeof(x) _x = (x); \
             const typeof(y) _y = (y); \
             (void) (&_x == &_y); \
             _x > _y ? _x : _y; })

Apparently this convoluted definition was adopted to prevent side-effects
from corrupting kernel-code when one of the arguments is evaluated twice as
in the usual definition

            #define min(a,b) ( ( (a) <= (b) ) ? (a) : (b))
            #define max(a,b) ( ( (a) >= (b) ) ? (a) : (b))

Does this mean that there's really bad kernel code that ignores the
side-effects issue?

    Norm



Relevant Pages