[package - head-amd64-default][games/simutrans] Failed for simutrans-120.2.2 in build
Tijl Coosemans
tijl at FreeBSD.org
Sat Jul 29 21:07:59 UTC 2017
On Sat, 29 Jul 2017 12:43:59 -0700 Mark Millard <markmi at dsl-only.net> wrote:
> 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:
>>>>> On 28 Jul 2017, at 13:55, Tijl Coosemans <tijl at freebsd.org> wrote:
>>>>>>
>>>>>> On Thu, 27 Jul 2017 21:42:01 +0000 pkg-fallout at FreeBSD.org wrote:
>>>>> ...
>>>>>>> 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)
>>>>>>> ^
>>>>>>
>>>>>> Simutrans code defines 'type' as a macro. Shouldn't libc++ headers use
>>>>>> _type or __type or something?
>>>>>
>>>>> 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.
>>>>>
>>>>> Note that this also doesn't work with libstdc++, e.g.:
>>>>>
>>>>> $ cat boom.cpp
>>>>> #define type "nope, this will not work"
>>>>> #include <type_traits>
>>>>>
>>>>> and then:
>>>>>
>>>>> $ 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...]
>>>>
>>>> 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 = void> struct enable_if;
>>> . . .
>>> template <class T, T v> typedef integral_constant {
>>> . . .
>>> typedef integral_constant<T,v> type;
>>> . . .
>>> };
>>
>> 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=8163 -I/usr/local/include/SDL -I/usr/local/include -D_REENTRANT -D_THREAD_SAFE -DCOLOUR_DEPTH=16 -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=c++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= but depending on a
>>> default that happens to end up with c++11 or
>>> later as the version to target.
>>
>> 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.
Since you've written three times the same thing here let me reply with
three times the same thing:
- Adding -std=c++98 still fails to compile with the same errors.
- The compiler default is C++98:
% c++ -x c++ -E -dM /dev/null | grep __cplusplus
#define __cplusplus 199711L
- A quick look at the libc++ headers makes it immediately obvious they
expose and use C++11 features in C++98 mode.
And of course these were the very first things I checked before writing
my first email.
More information about the freebsd-toolchain
mailing list