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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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
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
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
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