<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Dec 2, 2015 at 1:41 AM, Weitian Leung via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi all,<br></div><div><br>
    Consider the following code (full source code can be found in
    attachment)<br>
    <br>
    object.h<br>
    <blockquote type="cite">#define _DESTRUCTOR_IN_HEADER<br>
      <br>
      class Object<br>
      {<br>
      public:<br>
          Object();<br>
      #ifdef _DESTRUCTOR_IN_HEADER<br>
          ~Object()<br>
          {<br>
          }<br>
      #else<br>
          ~Object();<br>
      #endif<br>
      <br>
      private:<br>
          class Counter<br>
          {<br>
          public:<br>
              Counter()<br>
                  : _count(0)<br>
              {<br>
                  printf("Counter: %p %d\n", this, _count);<br>
              }<br>
      <br>
              ~Counter()<br>
              {<br>
                  printf("~Counter: %p %d\n", this, _count);<br>
              }<br>
      <br>
              void operator++()    { ++_count; }<br>
              void operator--()    { --_count; }<br>
      <br>
          private:<br>
              int _count;<br>
          };<br>
      <br>
          class Foo<br>
          {<br>
          public:<br>
              Foo() { ++counter(); }<br>
              ~Foo() { --counter(); }<br>
      <br>
          private:<br>
              Counter& counter()<br>
              {<br>
                  static Counter s_counter;<br>
                  return s_counter;<br>
              }<br></blockquote></div></div></blockquote><div><br></div><div>When you use -fvisibility-inlines-hidden, you give this function hidden visibility, so each DSO gets its own copy of the function. We also give each DSO its own copy of each inline function's static local variables. Thus the Object::Object() constructor in your shared library increments one counter, and the Object::~Object() destructor in your main binary decrements a different counter.</div><div><br></div><div>GCC appears to not make the static local variable hidden when it makes the surrounding function hidden. That makes sense, since -fvisibility-inlines-hidden is supposed to not change the semantics of the program unless you're comparing addresses of inline functions.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><blockquote type="cite">
          } foo;<br>
      };<br>
    </blockquote>
    object.cpp
    <blockquote type="cite">#include "object.h"<br>
      <br>
      Object::Object()<br>
      {<br>
      }<br>
      <br>
      #ifndef _DESTRUCTOR_IN_HEADER<br>
      Object::~Object()<br>
      {<br>
      <br>
      }<br>
      #endif</blockquote>
    <br>
    Build the source to a shared library (compile with
    -fvisibility-inlines-hidden flag),<br>
    uses in main (another module)<br>
    <blockquote type="cite">    Object *obj = new Object;<br>
          delete obj;</blockquote>
    you may see the strange output when running<br>
    <blockquote type="cite">Counter: 0x7f2ded933efc 0<br>
      Counter: 0x6012d4 0<br>
      ~Counter: 0x6012d4 -1<br>
      ~Counter: 0x7f2ded933efc 1</blockquote>
    <br>
    The Counter construct/destruct twice, the second one (Counter:
    0x6012d4 0) construct from<br>
     delete obj > Object::Foo::~Foo() > Object::Foo::counter()<br>
    <br>
    when comment out the line <b>#define _DESTRUCTOR_IN_HEADER </b>or
    remove the<b><br>
    </b><b>-fvisibility-inlines-hidden</b> flag, it works as expected<br>
    remove the compile flag<br>
    <blockquote type="cite">Counter: 0x6013a4 0<br>
      ~Counter: 0x6013a4 0</blockquote>
    comment out #define _DESTRUCTOR_IN_HEADER<br>
    <blockquote type="cite">Counter: 0x7f1eaa16629c 0<br>
      ~Counter: 0x7f1eaa16629c 0</blockquote>
    <br>
    A bit difference, as the address isn't the same (heap and stack)<br>
    <br>
    this code works with GCC (as least 5.2 as my test) with or without
    the -fvisibility-inlines-hidden<br>
    flag, of course it works with MSVC too.<br>
    <br>
    I don't known is this a bug with the flag or because the silly code
    makes it (as when constructor and<br>
    destructor defined in the same file, it works).<br><br></div><div>It seems that my last post failed, seems no body answers me, so I repost again, sorry.<br></div><div>If this is the wrong place, please let me know where to post, thanks.<br></div><div><br></div></div>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>