Author Topic: Linux: I can not compile simutrans  (Read 2587 times)

0 Members and 1 Guest are viewing this topic.

Offline Yona-TYT

Linux: I can not compile simutrans
« on: August 14, 2016, 12:59:43 PM »

I can not compile on Linux simutrans


Using fedora 24


Code: [Select]
make
===> HOSTCXX besch/bild_besch.cc
besch/bild_besch.cc: En la función miembro static ‘static bild_besch_t* bild_besch_t::create_single_pixel()’:
besch/bild_besch.cc:312:61: error: exception cleanup for this placement new selects non-placement operator delete [-fpermissive]
  bild_besch_t* besch = new(4 * sizeof(PIXVAL)) bild_besch_t();
                                                             ^
In file included from /usr/include/c++/6.1.1/ext/new_allocator.h:33:0,
                 from /usr/include/c++/6.1.1/i686-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/6.1.1/bits/allocator.h:46,
                 from /usr/include/c++/6.1.1/string:41,
                 from /usr/include/c++/6.1.1/bits/locale_classes.h:40,
                 from /usr/include/c++/6.1.1/bits/ios_base.h:41,
                 from /usr/include/c++/6.1.1/ios:42,
                 from /usr/include/c++/6.1.1/ostream:38,
                 from /usr/include/c++/6.1.1/iterator:64,
                 from besch/../display/../utils/for.h:4,
                 from besch/../display/../simtypes.h:9,
                 from besch/../display/../unicode.h:5,
                 from besch/../display/simgraph.h:18,
                 from besch/bild_besch.h:10,
                 from besch/bild_besch.cc:1:
/usr/include/c++/6.1.1/new:125:6: nota: ‘void operator delete(void*, std::size_t)’ is a usual (non-placement) deallocation function in C++14 (or with -fsized-deallocation)
 void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
      ^~~~~~~~
besch/bild_besch.cc: En la función miembro ‘bild_besch_t* bild_besch_t::copy_rotate(sint16) const’:
besch/bild_besch.cc:339:74: error: exception cleanup for this placement new selects non-placement operator delete [-fpermissive]
  bild_besch_t* target_besch = new(pic.len * sizeof(PIXVAL)) bild_besch_t();
                                                                          ^
In file included from /usr/include/c++/6.1.1/ext/new_allocator.h:33:0,
                 from /usr/include/c++/6.1.1/i686-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/6.1.1/bits/allocator.h:46,
                 from /usr/include/c++/6.1.1/string:41,
                 from /usr/include/c++/6.1.1/bits/locale_classes.h:40,
                 from /usr/include/c++/6.1.1/bits/ios_base.h:41,
                 from /usr/include/c++/6.1.1/ios:42,
                 from /usr/include/c++/6.1.1/ostream:38,
                 from /usr/include/c++/6.1.1/iterator:64,
                 from besch/../display/../utils/for.h:4,
                 from besch/../display/../simtypes.h:9,
                 from besch/../display/../unicode.h:5,
                 from besch/../display/simgraph.h:18,
                 from besch/bild_besch.h:10,
                 from besch/bild_besch.cc:1:
/usr/include/c++/6.1.1/new:125:6: nota: ‘void operator delete(void*, std::size_t)’ is a usual (non-placement) deallocation function in C++14 (or with -fsized-deallocation)
 void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
      ^~~~~~~~
besch/bild_besch.cc: En la función miembro ‘bild_besch_t* bild_besch_t::copy_flipvertical() const’:
besch/bild_besch.cc:388:74: error: exception cleanup for this placement new selects non-placement operator delete [-fpermissive]
  bild_besch_t* target_besch = new(pic.len * sizeof(PIXVAL)) bild_besch_t();
                                                                          ^
In file included from /usr/include/c++/6.1.1/ext/new_allocator.h:33:0,
                 from /usr/include/c++/6.1.1/i686-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/6.1.1/bits/allocator.h:46,
                 from /usr/include/c++/6.1.1/string:41,
                 from /usr/include/c++/6.1.1/bits/locale_classes.h:40,
                 from /usr/include/c++/6.1.1/bits/ios_base.h:41,
                 from /usr/include/c++/6.1.1/ios:42,
                 from /usr/include/c++/6.1.1/ostream:38,
                 from /usr/include/c++/6.1.1/iterator:64,
                 from besch/../display/../utils/for.h:4,
                 from besch/../display/../simtypes.h:9,
                 from besch/../display/../unicode.h:5,
                 from besch/../display/simgraph.h:18,
                 from besch/bild_besch.h:10,
                 from besch/bild_besch.cc:1:
/usr/include/c++/6.1.1/new:125:6: nota: ‘void operator delete(void*, std::size_t)’ is a usual (non-placement) deallocation function in C++14 (or with -fsized-deallocation)
 void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
      ^~~~~~~~
besch/bild_besch.cc: En la función miembro ‘bild_besch_t* bild_besch_t::copy_fliphorizontal() const’:
besch/bild_besch.cc:416:74: error: exception cleanup for this placement new selects non-placement operator delete [-fpermissive]
  bild_besch_t* target_besch = new(pic.len * sizeof(PIXVAL)) bild_besch_t();
                                                                          ^
In file included from /usr/include/c++/6.1.1/ext/new_allocator.h:33:0,
                 from /usr/include/c++/6.1.1/i686-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/6.1.1/bits/allocator.h:46,
                 from /usr/include/c++/6.1.1/string:41,
                 from /usr/include/c++/6.1.1/bits/locale_classes.h:40,
                 from /usr/include/c++/6.1.1/bits/ios_base.h:41,
                 from /usr/include/c++/6.1.1/ios:42,
                 from /usr/include/c++/6.1.1/ostream:38,
                 from /usr/include/c++/6.1.1/iterator:64,
                 from besch/../display/../utils/for.h:4,
                 from besch/../display/../simtypes.h:9,
                 from besch/../display/../unicode.h:5,
                 from besch/../display/simgraph.h:18,
                 from besch/bild_besch.h:10,
                 from besch/bild_besch.cc:1:
/usr/include/c++/6.1.1/new:125:6: nota: ‘void operator delete(void*, std::size_t)’ is a usual (non-placement) deallocation function in C++14 (or with -fsized-deallocation)
 void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT
      ^~~~~~~~
common.mk:50: fallo en las instrucciones para el objetivo 'build/default/besch/bild_besch.o'
make: *** [build/default/besch/bild_besch.o] Error 1


Offline DrSuperGood

Re: Linux: I can not compile simutrans
« Reply #1 on: August 14, 2016, 01:55:07 PM »
This is the issue I raised twice before already. Its due to C++14 adding sized dealocation for better optimization. This conflicts as it matches the deallocation function for the placement allocator used for hacky array support. It does not matter if such a dealocation function exists or not, the problem is that the placement allocator definition is now reserved due to the potential to conflict and so cannot be used.

The current solutions are to either compile with an older standard of C++ (earlier than C++14), or to use compile flags (if any) to disable sized deallaction functionality.

The reason it is a problem now is that apparently GCC/G++ forces the use of modern C++ standards by default (before they had to be specified by flags).

I plan to look into solutions to this in the future. The problem is finding a solution which does not break pre C++14 compilers.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4900
  • Total likes: 217
  • Helpful: 108
  • Languages: EN, NO
Re: Linux: I can not compile simutrans
« Reply #2 on: August 14, 2016, 03:17:57 PM »
It does not matter if such a dealocation function exists or not, the problem is that the placement allocator definition is now reserved due to the potential to conflict and so cannot be used.

Actually, it seems like it does matter. The standard was just unclear on whether a class specific allocation function will pair up with a global deallocation function when no class specific deallocation functions exist. Or the compiler just got that part wrong.

Offline isidoro

Re: Linux: I can not compile simutrans
« Reply #3 on: August 14, 2016, 10:12:49 PM »
@DrSuperGood: wouldn't -std=c++98 suffice?

Offline DrSuperGood

Re: Linux: I can not compile simutrans
« Reply #4 on: August 15, 2016, 12:49:19 AM »
Quote
Or the compiler just got that part wrong.
Both GCC and MSVC have done this though.

Quote
@DrSuperGood: wouldn't -std=c++98 suffice?
I honestly do not know. I recommend trying it and if that fails then trying something else.

The solution for MSVC 2015 was a specific compatibility flag, "/Zc:sizedDealloc-", which disables the sized deallocator functionality of C++14.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4900
  • Total likes: 217
  • Helpful: 108
  • Languages: EN, NO
Re: Linux: I can not compile simutrans
« Reply #5 on: August 15, 2016, 04:46:28 AM »
Does my quick fix work for MSVC 2015? If so, it might be a good idea to commit that until/if a better solution is found. If it only works on GCC, simply including -std=c++98 as a default build option should work just as well. (Although defining a custom deallocation function for each custom allocation function might be good practice.)

Offline DrSuperGood

Re: Linux: I can not compile simutrans
« Reply #6 on: August 15, 2016, 05:26:15 AM »
Quote
Does my quick fix work for MSVC 2015?
What fix are you referring to?

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4900
  • Total likes: 217
  • Helpful: 108
  • Languages: EN, NO
Re: Linux: I can not compile simutrans
« Reply #7 on: August 15, 2016, 02:38:08 PM »
The one I posted the last time we discussed this. I should perhaps have posted it in the original discussion for this issue, but that is on a non-public board.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4900
  • Total likes: 217
  • Helpful: 108
  • Languages: EN, NO
Re: Linux: I can not compile simutrans
« Reply #8 on: August 22, 2016, 07:58:04 PM »
I have now checked that simply adding
Code: [Select]
void operator delete(void *ptr) {
return ::operator delete(ptr);
}
will make the compiler I got with Visual Studio 2015 (that is compiler version 19.00.23026) stop complaining in a small test I made, whereas it will complain if this bit is missing when there is a placement allocation function similar to Simutrans'. I do not know if adding a using declaration in bild_besch_t is necessary for the delete operator as well, nor why the using declaration for the new operator is.

But I would like to know if anyone remembers if having the data inline is really performance critical. And why is there an intermediate bild_t structure? The display subsystem has its own imd structure, which is probably the performance critical one.

And I believe this topic should be in Technical Documentation, not in the Help Center. Could any moderators look into this?

Offline DrSuperGood

Re: Linux: I can not compile simutrans
« Reply #9 on: October 08, 2016, 02:49:57 AM »
Quote
will make the compiler I got with Visual Studio 2015 (that is compiler version 19.00.23026) stop complaining in a small test I made, whereas it will complain if this bit is missing when there is a placement allocation function similar to Simutrans'. I do not know if adding a using declaration in bild_besch_t is necessary for the delete operator as well, nor why the using declaration for the new operator is.
I can confirm that this does fix the problem on MSVC2015 (no more need for compiler flag work around) and will probably fix it on GCC as well. Will be committing the fix shortly. It probably fixes it by forcing the compiler to fall back to the normal delete operator rather than trying to use a standard sized delete operator which conflicts with the custom placement new operator.

I am guessing older compilers (pre sized delete operator) still had the normal delete operator so hopefully it will not break building on older compilers.

Quote
But I would like to know if anyone remembers if having the data inline is really performance critical.
Depends entirely on how many different times the appended data is accessed. Outside of the memory read for a pointer, once that is in registers it should perform similar to being an appended member array. Probably the biggest speed difference might from caching behaviour as the appended data is address wise near the rest of the object as opposed to being in a completely difference place in memory.

Offline Ters

  • Coder/patcher
  • Devotee
  • *
  • Posts: 4900
  • Total likes: 217
  • Helpful: 108
  • Languages: EN, NO
Re: Linux: I can not compile simutrans
« Reply #10 on: October 08, 2016, 08:37:25 AM »
I am guessing older compilers (pre sized delete operator) still had the normal delete operator so hopefully it will not break building on older compilers.
I was thinking that since this is nothing but a deallocator function matching the already existing (non-sized) allocator function, it should not cause any problems with older compilers either. If anything, I would except them to be happy to see it.

Depends entirely on how many different times the appended data is accessed. Outside of the memory read for a pointer, once that is in registers it should perform similar to being an appended member array. Probably the biggest speed difference might from caching behaviour as the appended data is address wise near the rest of the object as opposed to being in a completely difference place in memory.
I was thinking more about the bigger picture. How often is this memory accessed at all? If it is just once per bild_t per process, to convert the portable image format into the device dependent format in simgraph*.cc, it doesn't matter if it requires a few extra instructions and cache misses.