[GTALUG] Ubuntu 16.04 / gcc 5.4.0 - errors generated inside system include files
D. Hugh Redelmeier
hugh at mimosa.com
Sun Aug 7 15:34:24 EDT 2016
I installed AMD64 Ubuntu 16.04 LTS on another computer so that I could
play. But it turns out that the same problem is in Fedora 24 so I
needn't have bothered.
Aside: I learned that the best description of my Canadian Bilingual
Keyboard is under French(Canada) ; English-something-or-other.
I'm still playing with this, but here are my preliminary observations.
So here's the fundamental problem.
"exp" is kind of like a reserved word in C. It is the exponential
function and is declared in math.h.
logo.h has
#define exp expresn
This screws up math.h.
[language lawyer mode]
The C standard as of N1548 (draft from 2010 December 2) says:
7.1.2 Reserved identifiers
...
- All identifiers with external linkage in any of the following
subclauses (including the future library directions) and errno are
always reserved for use as identifiers with external linkage. 184)
...
A following subclause includes a definition of exp. As I understand it,
as an identifier with external linkage.
As I read that, logo.h is NOT impinging since it is using exp as a
macro name, something that gets "washed out" by the preprocessor, long
before external linkages are understood.
But the definition of exp affects the tricky code in
/usr/include/x86_64-linux-gnu/bits/mathcalls.h
__MATHCALL_VEC (exp,, (_Mdouble_ __x));
=>
__MATHCALL_VEC (expresn,, (_Mdouble_ __x));
which then malfunctions.
Math.h:
/* The file <bits/mathcalls.h> contains the prototypes for all the
actual math functions. These macros are used for those prototypes,
so we can easily declare each function as both `name' and `__name',
and can declare the float versions `namef' and `__namef'. */
#define __SIMD_DECL(function) __CONCAT (__DECL_SIMD_, function)
#define __MATHCALL_VEC(function, suffix, args) \
__SIMD_DECL (__MATH_PRECNAME (function, suffix)) \
__MATHCALL (function, suffix, args)
and so on.
I *think* that this is a bug in glibc (i.e. a "contract violation" of
the C Standard), but I'm not 100% sure.
Why does ucblogo have this definition? Here's my guess.
UCB Logo uses a global variable with the name "exp" pervasively. Then
it turned out that this was the (external linkage) name of the exp
function. So there was a clash, even though the exp function isn't
used by ucblogo. The #define was a simple way of renaming the global
variable's external name without editing the source code. An
effective hack.
Fix? Several, but untested.
1. Brutish of brute force:
Replace every
#include <math.h>
with
#undef exp
#include <math.h>
#define exp expresn
2. Better fix: fix glibc to not take names that don't belong to it.
3. Blame the victim fix: in UCB Logo, replace every "exp" with
"expresn" (or some other apt short name).
4. Simpler UCB Logo fix:
Move the <> includes before the "" includes.
Generally considered good style anyway.
There is a chance that logo.h includes things that intentionally
modify system headers. In that case, this fix will break these
modifications.
More information about the talk
mailing list