Search code examples
cgccglibc

global variable y0 conflicts with mathlib, cannot compile minimal C code


When compiling this code

#include <math.h>

double *y0;

int main()
{
   return 0;
}

with gcc 13.2.0 from latest debian-sid, I get the following error:

gcc -o a.out proof.c -Wall -lm
proof.c:3:9: error: 'y0' redeclared as different kind of symbol
    3 | double *y0;
      |         ^~
In file included from /usr/include/features.h:490,
                 from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
                 from /usr/include/math.h:27,
                 from proof.c:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:223:1: note: previous declaration of 'y0' with type 'double(double)'
  223 | __MATHCALL (y0,, (_Mdouble_));
      | ^~~~~~~~~~
make: *** [Makefile:6: proof] Error 1

Note that if I replace *y0 with a different name, e.g. *x0, it does not complain. Clearly there's a conflict of names with mathlib, but is this normal? should such kind of conflict be possible or is it a bug?


Solution

  • y0 is the name of a Bessel function implemented in the math library. You should not use this name for a global variable.

    Here is a list of the Bessel functions supported by most C math libraries, albeit not part of the C Standard as of C23:

    // Bessel functions of the first kind
    double j0(double);
    double j1(double);
    double jn(int, double);
    // Bessel functions of the second kind
    double y0(double);
    double y1(double);
    double yn(int, double);
    

    These functions have been part of the POSIX Standard since the beginning, they have been available on Unix since System V in 1983. The GNU math library for C supports them by default, along with many other extensions, but as they are not part of Standard C, the declarations are conditional in <math.h> and omitted if strict standard conformance is requested with a compiler option (-std=c89, -std=c99, -std=c11, etc.).