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>