The International Simutrans Forum

Simutrans Extended => Simutrans-Extended development => Simutrans-Extended bug reports => Topic started by: jamespetts on May 25, 2020, 12:10:00 PM

Title: Compile error with GCC 10
Post by: jamespetts on May 25, 2020, 12:10:00 PM
A user has reported being unable to compile Simutrans-Extended with GCC 10. The reported error is:


bauer/../dataobj/livery_scheme.h:28:23:

/usr/include/c++/10.1.0/type_traits:960:52: Error: template argument
must be a complete class or an unbounded array
  960 |
static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),


I have not been able to find any intelligible explanation of how this error might arise in the web page concerned with porting from GCC 9 to GCC 10 (https://gcc.gnu.org/gcc-10/porting_to.html).

The relevant line on which compilation fails is:


vector_tpl<livery_t> liveries;


"livery_t" is a struct defined as:


struct livery_t
{
std::string name;
uint16 intro_date;
};


The relevant include is present in the header file:


#include <string>


I am afraid that I do not understand this error at all and have not been able to find any intelligible information at all on the error, "Error: template argument must be a complete class or an unbounded array" so as to try to work out what the problem might be.

I should be grateful for any assistance from anyone with any understanding of GCC 10, what this error is and how it might arise.
Title: Re: Compile error with GCC 10
Post by: ceeac on May 25, 2020, 01:57:18 PM
std namespace woes again ... GCC tries to use std::swap instead of the swap defined in vector_tpl.h. IMO the "using namespace std" should really be removed sooner than later to avoid issues like this. Anyway, the compile error should be fixed by #181 (https://github.com/jamespetts/simutrans-extended/pull/181).
Title: Re: Compile error with GCC 10
Post by: jamespetts on May 25, 2020, 02:28:08 PM
Thank you for that - that is extremely helpful. This is now incorporated.

As to removing "using namespace std", I do not know how one might go about this without breaking anything else.
Title: Re: Compile error with GCC 10
Post by: Mariculous on May 25, 2020, 03:07:51 PM
remove it and explicitly prefix calls to STL functions by "std::".
e.g. instead of
using namespace std;
...
min(1,2);


use
sdt::min(1,2)
Title: Re: Compile error with GCC 10
Post by: jamespetts on May 25, 2020, 03:12:57 PM
With min/max, the complexity is that there are actually bespoke Simutrans functions for these, albeit they do not work properly for 64-bit variables.
Title: Re: Compile error with GCC 10
Post by: Mariculous on May 25, 2020, 04:09:18 PM
Yes, so use std::min and std::max to use the functions from STL and simply min or max to use the (non namespaced) simutrans functions.
In both cases the headers need to be included for sure.
Title: Re: Compile error with GCC 10
Post by: jamespetts on May 25, 2020, 04:12:37 PM
Quote from: Freahk on May 25, 2020, 04:09:18 PM
Yes, so use std::min and std::max to use the functions from STL and simply min or max to use the non namespaced) simutrans functions.
Both assume the headers are included for sure.

I am not sure why we want to use the simutrans implementation of such STL functions anyways.

This is a legacy from Standard - I am not sure whether any of the Standard developers know the basis for this or whether there is any reason for retaining this?
Title: Re: Compile error with GCC 10
Post by: Mariculous on May 25, 2020, 05:01:06 PM
Exactly, I'd expect it to exist for legacy reasons.
C++ stdlib was first introduced in C++98, where simutrans started in 1997?
I have no idea when C++98 was first introduced to simutrans.
Many of simutrans stdlib duplicates seem to be quite old, so I'd expect these to exist because the std variant was simply not available to simutrans at that time and nobody refactored the code later on.

Don't get me wrong, I'm not saying we should refactor the whole code, but imho stdlib features should be used for new code or when doing changes in the code anyway.

Title: Re: Compile error with GCC 10
Post by: TurfIt on May 25, 2020, 06:31:12 PM
IMO the std::min/max should completely replace the dangerous Simutrans defined ones. Far too easy for "bad things" happening with them  (compiler silently passing uint32 as sint32 and....)
I'd started to do so after falling into that trap one too many times, but as usual never finished - probably useless now patch attached, it's for standard and 3 years old. Never finished verifying the explicit types. [you can't just change max() to std::max() as the compiler is too dumb to deduce the type quite often. e.g. need std::max<uint32>()]

Title: Re: Compile error with GCC 10
Post by: ceeac on May 25, 2020, 07:07:21 PM
Quote from: TurfIt on May 25, 2020, 06:31:12 PM[you can't just change max() to std::max() as the compiler is too dumb to deduce the type quite often. e.g. need std::max<uint32>()]
An improvement might be something like this which allows comparing types of same signedness, but not mixed:

namespace sim {
template<typename T1, typename T2, typename R = typename std::enable_if<std::is_signed<T1>::value == std::is_signed<T2>::value, typename std::common_type<T1, T2>::type>>
R min(const T1 &a, const T2 &b)
{
return a < b ? a : b;
}
}

Requires C++11, so it's not for Standard.