News:

The Forum Rules and Guidelines
Our forum has Rules and Guidelines. Please, be kind and read them ;).

Compile error with GCC 10

Started by jamespetts, May 25, 2020, 12:10:00 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

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.

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.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

ceeac

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.

jamespetts

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.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Sirius

#3
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)

jamespetts

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.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Sirius

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.

jamespetts

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?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

Sirius

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.


TurfIt

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>()]


ceeac

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.