Package: libkpathsea-dev
Version: 2024.20240313.70630+ds-6
Severity: important
Tags: ftbfs upstream forky sid
Control: block 1096597 by -1
Control: affects -1 + src:evince

In #1096597, Matthias Klose reported that evince FTBFS with gcc-15 as 
default (it is not the default for trixie, but will become the default 
in forky). This seems to be caused by libkpathsea-dev's headers, 
combined with gcc-15 defaulting to C23.

As an example of the class of issue I'm reporting, libkpathsea-dev's 
c-std.h has this:

>#ifdef HAVE_STDLIB_H
>#include <stdlib.h>
>/* Include <stdlib.h> before <stddef.h>, to help avoid NULL
>   redefinitions on some systems.  (We don't include <stddef.h>
>   ourselves any more, but FYI.)  */
>#else
>/* It's impossible to say for sure what the system will deign to put in
>   <stdlib.h>, but let's hope it's at least this.  */
>extern char *getenv ();
>#endif /* not HAVE_STDLIB_H */

and evince includes <stdlib.h> followed by <kpathsea/c-std.h>.

The code in c-std.h assumes that the build system of every dependent 
package will check for stdlib.h and define HAVE_STDLIB_H if found, but 
there is a tendency to stop doing that, and instead assume that all 
platforms comply with a 1989 C standard by now. In particular Evince 
does not check for <stdlib.h>, and includes it unconditionally (I 
assume).

In C11 or older, `extern char *getenv ()` declares getenv() as a 
function taking unspecified parameters and returning a string, but in 
C23 it declares getenv() as a function taking *no* parameters and 
returning a string, hence the compiler sees this as a declaration that 
is incompatible with the one it already saw in <stdlib.h>, and errors 
out:

>/usr/include/kpathsea/c-std.h:48:14: error: conflicting types for ‘getenv’; 
>have ‘char *(void)’
>   48 | extern char *getenv ();
>      |              ^~~~~~

An equivalent failure mode is seen in the evince build log for other 
Standard C functions like strtok() and strstr(). There might be others, 
I didn't inspect all of the kpathsea headers.

evince could presumably work around this by conditionally or 
unconditionally defining HAVE_STDLIB_H, etc., before it includes 
kpathsea headers; but it shouldn't have to, because each library should 
be self-contained.

I think <kpathsea/c-std.h> should do something more like this 
(pseudo-patch, untested) so that it treats __STDC__ as implying that 
every Standard C header is present:

-#ifdef HAVE_STDLIB_H
+#if defined(__STDC__) || defined(HAVE_STDLIB_H)
 #include <stdlib.h>
...

(or it could check __STDC_VERSION__ if preferred)

... or it could just assume that every platform has Standard C headers 
by now, since C89 is several decades old.

Thanks,
    smcv

Reply via email to