Slog Inheiritance

Help
schwartz
2006-08-25
2012-11-20
  • schwartz

    schwartz - 2006-08-25

    When building Class Slog I find the following code:

    Slog::Slog(void) :
    streambuf()
    #ifdef    HAVE_OLD_IOSTREAM
    ,ostream()
    #else
    ,ostream((streambuf *)this)
    #endif
    {
    #ifdef    HAVE_OLD_IOSTREAM
        init((streambuf *)this);
    #endif
        _enable = true;
        _level = levelDebug;
        _clogEnable = true;
    #ifndef    HAVE_SYSLOG_H
        syslog = NULL;
    #endif
    }

    I am not defining HAVE_OLD_IOSTREAM so the class tries to initiate ostream((streambuf *)this)my compiler (VC++ 8.0) warns me about using "this" in a base member initialization list. 

    The compiler is quite right, as when the constructor for ostream is called, that "this" is not defined.  Shouldn't the constructor call init(this) as is done when HAVE_OLD_IOSTREAM is defined?

    Paul

     
    • Buck

      Buck - 2006-08-25

      interesting. i'll chime in, just to give you
      something to think about, and then someone
      will jump in and put a stop to the madness if
      i've totally misled you

      (*this) may not be well defined, but i believe that
      the address (this) itself is determined by the time
      the constructor initializer list is processed, since, if you reckon (though i suppose reading
      the standard is what the gurus and their books
      would probably suggest instead) that, if you use
      the placement-new operator, then you're telling the
      constructor what (this) is (or something to use
      as the sole basis from determining (*this),
      presumably before the initializers are run). of
      course, if the ostream() constructor does anything
      with *this before it's fully constructed, well,
      that's probably wrong, as opposed to just possibly
      ill-advised

       
    • schwartz

      schwartz - 2006-08-25

      Well this (no pun inteneded) is how I see it.

      If *this where a pointer to a pointer then the value could be filled in later, but it's not. I suppose ostream might dereference the *this pointerand take the adress of where the *this pointer is stored and use that reference later.

      I guess I'll have to dive into the ostream (basic_stream) class contructor and see how the *this value is really used.

      If the ostream class uses the streambuf pointer that *this is being cast to for any thing other than getting the locatin where it's going to be stored, then something isn't right. And I am suprized this issue hasn't come up before.  

      Maybe other compilers didn't check for this type of initialization.  I dunno.

      Paul

       
      • Buck

        Buck - 2006-08-26

        actually, what's being passed in (this), not
        (*this), so it is a pointer. as for the ostream
        constructor, whether it's called in the initializer
        list or in the body of the constructor, it's still
        not getting a fully constructed object pointer,
        but my guess is that, given the name of the member,
        it's a derivative of std::basic_ostream<...>,
        which, in the libstdc++ headers on my Linux machine,
        contains the following:

              // [27.6.2.2] constructor/destructor
              /**
               *  @brief  Base constructor.
               *
               *  This ctor is almost never called by the user directly, rather from
               *  derived classes' initialization lists, which pass a pointer to
               *  their own stream buffer.
              */
              explicit
              basic_ostream(__streambuf_type* __sb)
              { this->init(__sb); }

        so i guess the initializer-list idiom is
        acceptable, for use with GNU's libstdc++,
        if ostream is what i'm guessing it is, albeit
        possibly not a base but a member

         
        • schwartz

          schwartz - 2006-08-26

          Actually, it is a base class.

          the class  for Slog is

          class __EXPORT Slog : protected std::streambuf, public std::ostream

          ...

          And the constructor is

          Slog::Slog(void) :
          streambuf()
          #ifdef    HAVE_OLD_IOSTREAM
          ,ostream()
          #else
          ,ostream((streambuf *)this)
          #endif
          {

          Therefore this should be undefined. 

          This construction appears for several other classes of more importance than Slog.

          It's possible this doesn't cause a proble, but it's risky.

          Paul

           

Log in to post a comment.