Thread overview
Compile error: function name collisions between port.h and math.h?
Apr 05, 2007
mpb
Apr 05, 2007
mpb
Apr 05, 2007
James Dennett
Apr 05, 2007
Thomas Kuehne
April 05, 2007
Hi,

I get a compile error when I try to compile GDC 0.23 against GCC 4.0.1, 4.0.4, 4.1.1 or 4.1.2.

./gcc/d/dmd/port.h:37: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:37: error: expected `)' before 'sizeof' ./gcc/d/dmd/port.h:38: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:38: error: expected `)' before 'sizeof' ./gcc/d/dmd/port.h:40: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:40: error: expected `)' before 'sizeof'

GCC (without D) compiles fine.  I'm running on Linux 2.6.12 with glibc 2.4 and compiling with GCC 4.1.1.

port.h lines 37 through 40 are part of the declaration of struct Port:

    static int isnan(double);
    static int isfinite(double);
    static int isinfinity(double);
    static int signbit(double);

It is interesting that line 39, while very similar, does not generate an error.

The command that causes the error is:

c++   -O2 -march=i686 -fomit-frame-pointer -pipe -DIN_GCC   -W -Wall
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes     -DHAVE_CONFIG_H
-I. -Id -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc
-I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d
-I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/../include
-I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/../libcpp/include
 -Id -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd
-I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d -D_GNU_SOURCE=1
-D_DH=1 -DD_NO_TRAMPOLINES=1 -DELFOBJ=1 -DD_GCC_VER=40 -Wno-missing-braces
-fmessage-length=0 -include
/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd/total.h -o
d/expression.dmd.o -c
/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd/expression.c

The command also generates approximately 180 warnings.

The errors might be due to collisions with similarly named functions in math.h.

Any help resolving the problem would be appreciated.

Thanks!

-mpb
April 05, 2007
mpb wrote:

> GCC (without D) compiles fine.  I'm running on Linux 2.6.12 with glibc
> 2.4 and compiling with GCC 4.1.1.

I haven't run into this issue before, strangely enough...
But looking at the header file, I can see how it can be.

They call three diffent lib functions, depending on the
sizeof of the actual argument, e.g. isnanf/isnan/isnanl

> port.h lines 37 through 40 are part of the declaration of struct Port:
> 
>     static int isnan(double);
>     static int isfinite(double);
>     static int isinfinity(double);
>     static int signbit(double);
> 
> It is interesting that line 39, while very similar, does not generate
> an error.

This is because there is no #define for isinfinity.

> The errors might be due to collisions with similarly named functions
> in math.h.

Similarly named *macros* that is, not functions...

> Any help resolving the problem would be appreciated.

At the top of port.h, it needs to include <math.h>
and then strip it from the use of any such macros:

#include <math.h>
#undef isnan
#undef isfinite
#undef signbit

If the code including "port.h" actually uses those,
it's possible to store them away and restore later:

#define OLD_foo	foo
#undef foo
...
#define foo OLD_foo

--anders
April 05, 2007
Anders wrote:

> I haven't run into this issue before, strangely enough... But looking at the header file, I can see how it can be.

It is puzzling that no one had this problem before.

expression.c clearly and directly includes math.h before port.h.  So it seems this problem would always happen.

Instead of undefining macros, I simply changed expression.c to include port.h *before* math.h.  This allowed me to compile expression.c to expression.dmd.o.

expression.c appears to be the only file than includes both math.h and port.h.

Including math.h before port.h seems to me like a bug worth fixing upstream in DMD itself, or at least in GDC.  I'm not sure where/how to submit such a bug report.

Thanks!

-mpb
April 05, 2007
mpb schrieb am 2007-04-05:
> Hi,
>
> I get a compile error when I try to compile GDC 0.23 against GCC 4.0.1, 4.0.4, 4.1.1 or 4.1.2.

I've successfully compiled gdc-0.23 with vanilla 4.1.2 as well as a Gentoo patched 4.1.2.

> ./gcc/d/dmd/port.h:37: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:37: error: expected `)' before 'sizeof' ./gcc/d/dmd/port.h:38: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:38: error: expected `)' before 'sizeof' ./gcc/d/dmd/port.h:40: error: expected unqualified-id before 'sizeof' ./gcc/d/dmd/port.h:40: error: expected `)' before 'sizeof'
>
> GCC (without D) compiles fine.  I'm running on Linux 2.6.12 with glibc 2.4 and compiling with GCC 4.1.1.

Judging from the messages below you might be compiling with 4.1.1 but the gcc you are compiling seems to be 4.0.4.

> port.h lines 37 through 40 are part of the declaration of struct Port:
>
>     static int isnan(double);
>     static int isfinite(double);
>     static int isinfinity(double);
>     static int signbit(double);
>
> It is interesting that line 39, while very similar, does not generate an error.
>
> The command that causes the error is:
>
> c++   -O2 -march=i686 -fomit-frame-pointer -pipe -DIN_GCC   -W -Wall
> -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes     -DHAVE_CONFIG_H
> -I. -Id -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc
> -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d
> -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/../include
> -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/../libcpp/include
>  -Id -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd
> -I/home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d -D_GNU_SOURCE=1
> -D_DH=1 -DD_NO_TRAMPOLINES=1 -DELFOBJ=1 -DD_GCC_VER=40 -Wno-missing-braces
> -fmessage-length=0 -include
> /home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd/total.h -o
> d/expression.dmd.o -c
> /home/zu20070220/Files/Compile/Sources/gcc-4.0.4/./gcc/d/dmd/expression.c
>
> The command also generates approximately 180 warnings.
>
> The errors might be due to collisions with similarly named functions in math.h.

The problem is that <math.h> doesn't define a function for isnan but a macro.

Lets try to edit d/dmd/expression.c:
Move "#include <math.h>" to line 60 and try to recompile.

Thomas


April 05, 2007
mpb wrote:

> Including math.h before port.h seems to me like a bug worth fixing upstream in DMD
> itself, or at least in GDC.  I'm not sure where/how to submit such a bug report.

http://d.puremagic.com/issues/

--anders
April 05, 2007
mpb wrote:

> Instead of undefining macros, I simply changed expression.c to include port.h
> *before* math.h.  This allowed me to compile expression.c to expression.dmd.o.

That fixes it temporarily, until something else includes port.h too :-P

BTW:
Had a similar matter in Code::Blocks recently, where someone did an enum
for different platforms: windows, linux, macosx (and so on and so forth)
It's just that "linux" is a predefined macro, so the code broke there...
Eventually it was worked around by adding -Ulinux to the CPPFLAGS. Ouch.

--anders
April 05, 2007
Anders F Björklund wrote:
> If the code including "port.h" actually uses those,
> it's possible to store them away and restore later:
> 
> #define OLD_foo    foo

This doesn't remember the definition of foo; it just
makes OLD_foo expand to the token "foo".  (As macro
replacement is somewhat recursive, that would then
be expanded if a macro called foo was defined in the
relevant context of use.)

> #undef foo

So here, OLD_foo just expands to foo.

> ...
> #define foo OLD_foo

And now there's a loop, but the C preprocessor rules
stop the infinite recursion, so foo is defined as a
macro which ultimately expands to foo, and OLD_foo
expands to OLD_foo, in effect just as if you had
done

#define foo foo
#define OLD_foo OLD_foo

Sorry; the C preprocessor really doesn't give any
nice to way handling scoping of definitions.

-- James
April 05, 2007
James Dennett wrote:

> Sorry; the C preprocessor really doesn't give any
> nice to way handling scoping of definitions.

Nah, it was just a quick thought on how I usually
handle symbol conflicts - but only for constants...

But it doesn't work in this case, as you point out.
The #include rearrangement will have to do for now.

--anders