Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Jul 2017 00:34:39 -0700
From:      Mark Millard <markmi@dsl-only.net>
To:        Tijl Coosemans <tijl@FreeBSD.org>
Cc:        Dimitry Andric <dim@FreeBSD.org>, toolchain@FreeBSD.org
Subject:   Re: [package - head-amd64-default][games/simutrans] Failed for simutrans-120.2.2 in build
Message-ID:  <D780E949-FB27-4A84-8E10-75D1E7A8EA06@dsl-only.net>
In-Reply-To: <20170729015914.184c2660@kalimero.tijl.coosemans.org>
References:  <201707272142.v6RLg1G4099900@beefy12.nyi.freebsd.org> <20170728135510.2c6de57f@kalimero.tijl.coosemans.org> <F47E0976-759A-45A0-8421-8FD4402A9980@FreeBSD.org> <20170729015914.184c2660@kalimero.tijl.coosemans.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 2017-Jul-28, at 4:59 PM, Tijl Coosemans <tijl at FreeBSD.org> wrote:

> On Fri, 28 Jul 2017 19:54:04 +0200 Dimitry Andric <dim at FreeBSD.org> =
wrote:
>> On 28 Jul 2017, at 13:55, Tijl Coosemans <tijl@freebsd.org> wrote:
>>>=20
>>> On Thu, 27 Jul 2017 21:42:01 +0000 pkg-fallout@FreeBSD.org wrote: =20=

>> ...
>>>> In file included from squirrel/squirrel/sqvm.cc:5:
>>>> In file included from /usr/include/c++/v1/math.h:310:
>>>> /usr/include/c++/v1/limits:149:85: error: expected expression
>>>>   _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() =
_NOEXCEPT {return type();}
>>>>                                                                     =
              ^
>>>> squirrel/squirrel/sqobject.h:131:24: note: expanded from macro =
'type'
>>>> #define type(obj) ((obj)._type)
>>>>                      ^ =20
>>>=20
>>> Simutrans code defines 'type' as a macro.  Shouldn't libc++ headers =
use
>>> _type or __type or something? =20
>>=20
>> No, the member name 'type' is used in many classes in the C++ =
standard
>> library, for example all the traits in <type_traits>.  Programs =
should
>> not attempt to redefine this, at least not as a macro.
>>=20
>> Note that this also doesn't work with libstdc++, e.g.:
>>=20
>> $ cat boom.cpp
>> #define type "nope, this will not work"
>> #include <type_traits>
>>=20
>> and then:
>>=20
>> $ g++ -c boom.cpp
>> boom.cpp:1:14: error: expected unqualified-id before string constant
>> #define type "nope, this will not work"
>>              ^
>> boom.cpp:1:14: error: expected class-name before string constant
>> #define type "nope, this will not work"
>>              ^
>> boom.cpp:1:14: error: expected '{' before string constant
>> boom.cpp:1:14: error: expected class-name before string constant
>> #define type "nope, this will not work"
>>              ^
>> boom.cpp:1:14: error: expected '{' before string constant
>> boom.cpp:1:14: error: expected class-name before string constant
>> #define type "nope, this will not work"
>>              ^
>> boom.cpp:1:14: error: expected '{' before string constant
>> boom.cpp:1:14: error: expected class-name before string constant
>> #define type "nope, this will not work"
>>              ^
>> boom.cpp:1:14: error: expected '{' before string constant
>> boom.cpp:1:14: error: expected unqualified-id before string constant
>> #define type "nope, this will not work"
>>              ^
>> In file included from boom.cpp:3:0:
>> /usr/local/lib/gcc6/include/c++/type_traits:212:60: error: template =
argument 1 is invalid
>>     : public __is_void_helper<typename remove_cv<_Tp>::type>::type
>>                                                            ^
>> /usr/local/lib/gcc6/include/c++/type_traits:212:61: error: expected =
'{' before '::' token
>>     : public __is_void_helper<typename remove_cv<_Tp>::type>::type
>>                                                             ^~
>> [...and lots more errors like this...]
>=20
> The code does not include <type_traits> or any of that C++11 stuff.  =
It
> includes <math.h>.  This works with libstdc++ because it doesn't have
> <math.h>, but it would also work when <cmath> was included, because
> libstdc++ uses __type everywhere (and __enable_if and __is_arithmetic,
> etc. where libc++ headers use enable_if and is_arithmetic).  The
> libstdc++ way makes more sense.  You cannot expect C++98 code to know
> about reserved identifiers in C++11 or C++11 code to know about =
reserved
> identifiers in later standards.

I'll first note that Annex D D.5 C standard library
headers says:

"the C++ standard library provides the 25 C headers,
as shown in table 154"

and table 154 lists: <math.h> . That is relevant
for the below.

ISO/IEC 14882:2011(E) 17.6.4.3.1 Macro Names
says:

"A translation unit that include a standard library
header shall not #define or #undef names declared
in any standard library header."

I'll note that the standard has sections with titles
like "Type names", "Class names", "Nested type names",
"Names of template specializations", and "Predefined
macro names". My understanding is that the earlier
quote spans avoiding matching all such names.



ISO/IEC 14882:2011(E) mandates such things as:

template <bool, class T> struct is_arithmetic;
. . .
template <bool, class T =3D void> struct enable_if;
. . .
template <class T, T v> typedef integral_constant {
. . .
   typedef integral_constant<T,v> type;
. . .
};

For targeting -std=3Dc++11 or later in compiles
__enable_if and __is_arithemtic and __type
would be wrong in these places and require
code using the standard to use the names
that have the __ prefixes, in violation of
the standard's specifications. That includes
having no explicit -std=3D but depending on a
default that happens to end up with c++11 or
later as the version to target.

As I remember the standard  makes few or no
guarantees about avoiding implicitly getting
more of the library header definitions than
the #includes explicitly reference in the
using code.

Your wording fits better for identifiers
that have no such mandated existence in
any part of the library for the c++??
being targeted in the compile. (It is
not the source code's intended target
that directly matters: just the actual
compile target.)

The library identifiers that required under
any version of the C++ standard are not
C++ keywords under that standard. In a
free-standing implementation the C++ keywords
are a much higher percentage of the relevant
names to avoid matching with macro names.

Also it would seem a good idea to explicitly
target the language version the code is designed
for, such as using -std=3Dc++98 . Otherwise one
needs to handle whatever the default version
may be --and so handle being compatible with
all official versions, not just the one for
the original design/intent.

Picking project-local macro names unlikely
to match code that one does not control
also seems to be a good idea. Some names
are far more likely than others. "type"
is rather generic.

=3D=3D=3D
Mark Millard
markmi at dsl-only.net




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?D780E949-FB27-4A84-8E10-75D1E7A8EA06>