Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

gcc

glibc

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?

like image 642
cipper Avatar asked Jun 29 '26 20:06

cipper


2 Answers

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.).

like image 195
chqrlie Avatar answered Jul 01 '26 14:07

chqrlie


double y0( double ) is a POSIX function with a prototype in math.h:

The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided.

double      acos(double);
float       acosf(float);
   .
   .
   .
double      y0(double);
double      y1(double);
double      yn(int, double);

y0 is therefore a reserved identifier:

  1. Each identifier with external linkage described in the header section is reserved for use as an identifier with external linkage if the header is included.

  2. Each macro described in the header section is reserved for any use if the header is included.

like image 28
Andrew Henle Avatar answered Jul 01 '26 14:07

Andrew Henle