[package - head-amd64-default][games/simutrans] Failed for simutrans-120.2.2 in build
Mark Millard
markmi at dsl-only.net
Sat Jul 29 19:44:09 UTC 2017
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.
===
Mark Millard
markmi at dsl-only.net
More information about the freebsd-toolchain
mailing list