On Sat, 29 Jul 2017 12:43:59 -0700 Mark Millard <mar...@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. _______________________________________________ freebsd-toolchain@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"