gnucap-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnucap-devel] link order


From: Christian Gagneraud
Subject: Re: [Gnucap-devel] link order
Date: Sat, 29 Jun 2019 22:10:24 +1200

On Sat, 29 Jun 2019 at 20:45, Felix Salfelder <address@hidden> wrote:
>
> On Sat, Jun 29, 2019 at 03:28:29PM +1200, Christian Gagneraud wrote:
> > > [..] static objects are initialised to zero.
> > No, that is not mandated by the C++ standard.
>
> Hi Christian.
>
> this is interesting.
>
> can you give a reference to this? here [1] they tell the opposite.  your
> claim is, if i understand, that static variables are not necessarily
> initialised to zero (note "initialisation" vs "construction").

Hi Felix,

Your static instance of DISPATCHER_BASE is indeed default constructed
(if you don't pass parameter)
but its _map pointer doesn't have a defined value, unless you default
initialise it.
class DISPATCHER_BASE {
  map *_map = nullptr;
}
or the old style
class DISPATCHER_BASE {
  DISPATCHER_BASE(): _map(nullptr) {}
  map *_map;
}

> > class DISPATCHER_BASE {
> > protected:
> >   std::map<std::string, CKT_BASE*> * _map; // (*)
> > private:
> >   explicit DISPATCHER_BASE(DISPATCHER_BASE*) {unreachable();incomplete();}
> > public:
> >   DISPATCHER_BASE() /*: _map(new std::map<std::string, CKT_BASE*>)*/ {
> >     if (!_map) {

this if is undefined behaviour, since _map is unitialised, in practice
this branch will be taken if it happens that the memory pointed to by
_map is actually all zero.
Which is what you have mainly encountered.


> >       _map = new std::map<std::string, CKT_BASE*>;
> >     }else{unreachable();
> >       puts("build error: link order: constructing dispatcher that already
> > has contents\n");
> >     }

But yes, every now and then this can happen. because _map is not initialised.

>
> > You should either:
> >  explicitly initialise the member when declaring it, eg std::map<X, Y>
> > *m_map = nullptr;
>
> what is the effect of std::map<X, Y> *m_map = nullptr;?
> are there multiple layers of construction in a newer C++? then i suggest
> to pass -std=c++98 (or c++11?) to the compiler, and see if it works.
>
> > or even better, do not use pointer to map, just use map.
> > But i guess you tried and it didn't work.
>
> yes it does, but it does not print an error in case the link order is
> wrong anymore. here's the pending commit [2], with the open question
> "(is there a better way?)". help appreciated!

I had a look at the code, first locally (DISPATCHER_BASE) and then I
followed their usage.
My understanding is that you have a system of static plugin.
A static plugin system implemented using static variable simply
doesn't work. The order in which all these static variables is not
defined.

I once had to maintain a code base with such a 'static plugin system'.
It worked well for ages, and one day I had to manage 2 version of an
arm-linux-gcc toolchain (from different vendors).

One of the toolchain would provoke early crashes.
The fix was to reverse the link order of the executable, this was a
makefile based project, and i had a special rule that depended of the
version of gcc, to handle the link order.

Well, i'm actually not sure i'm looking at the right thing, there was
no CMake file in there.
I was looking at master from git://git.savannah.gnu.org/gnucap.git

Chris


>
> cheers
> felix
>
> [1] 
> https://stackoverflow.com/questions/2091499/why-are-global-and-static-variables-initialized-to-their-default-values
> [2] 
> https://git.savannah.gnu.org/cgit/gnucap.git/commit/?h=pending&id=847095f7965e4f92e8c124817c8f855f560387dd



reply via email to

[Prev in Thread] Current Thread [Next in Thread]