Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Jul 2017 12:43:59 -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:  <D4345C7E-29E1-42CC-B970-82EF6439237A@dsl-only.net>
In-Reply-To: <20170729212706.33841c4c@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> <D780E949-FB27-4A84-8E10-75D1E7A8EA06@dsl-only.net> <20170729212706.33841c4c@kalimero.tijl.coosemans.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2017-Jul-29, at 12:27 PM, Tijl Coosemans <tijl at FreeBSD.org> wrote:

> On Sat, 29 Jul 2017 00:34:39 -0700 Mark Millard <markmi at =
dsl-only.net> wrote:
>> 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: =20
>>>> On 28 Jul 2017, at 13:55, Tijl Coosemans <tijl at freebsd.org> =
wrote: =20
>>>>>=20
>>>>> On Thu, 27 Jul 2017 21:42:01 +0000 pkg-fallout at FreeBSD.org =
wrote:   =20
>>>> ... =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
>>>=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. =20
>>=20
>> I'll first note that Annex D D.5 C standard library
>> headers says:
>>=20
>> "the C++ standard library provides the 25 C headers,
>> as shown in table 154"
>>=20
>> and table 154 lists: <math.h> . That is relevant
>> for the below.
>>=20
>> ISO/IEC 14882:2011(E) 17.6.4.3.1 Macro Names
>> says:
>>=20
>> "A translation unit that include a standard library
>> header shall not #define or #undef names declared
>> in any standard library header."
>>=20
>> 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.
>>=20
>>=20
>>=20
>> ISO/IEC 14882:2011(E) mandates such things as:
>>=20
>> 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;
>> . . .
>> };
>=20
> But none of this should be exposed to C++98 code.

Only if the compiler is told to compile the code as
C++98 code or it is known that C++98 is the default
target version for the compiler.

The compiler command that you published as part of
the error report provides no such explicit control
of what language/library version rules are to be
used:

c++ -O2 -pipe -fstack-protector -fno-strict-aliasing  -O2 -pipe  =
-fstack-protector -fno-strict-aliasing  -DNDEBUG -Wall -W -Wcast-qual =
-Wpointer-arith -Wcast-align -DUSE_C -DREVISION=3D8163 =
-I/usr/local/include/SDL -I/usr/local/include -D_REENTRANT =
-D_THREAD_SAFE -DCOLOUR_DEPTH=3D16 -c -MMD -o =
build/default/squirrel/squirrel/sqvm.o squirrel/squirrel/sqvm.cc

So if the default is to compile for C++11 or later
the results of using the C++11 rules are the expected
results here.

> These names were not
> reserved in the C++98 standard so C++98 code is free to use them.  If
> libc++ cannot compile such valid C++98 code it is simply not compliant
> with that standard.  Note that in this case we were lucky to see a
> diagnostic.  C++98 code may use these names in a way that doesn't =
cause
> an error.  Who's going to review our 27000 ports to make sure they are
> still compiled correctly?

Unless you tell the compiler to use C++98 rules you get the
rules of whatever version it targets by default.

>> 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.
>=20
> Of course things like __enable_if are for internal use only.  In C++11
> mode enable_if needs to be made available.

And if the compiler default version target was
C++11 or later then what it did was what it should
have done.


=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?D4345C7E-29E1-42CC-B970-82EF6439237A>