[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