Nikolai Pretzell wrote:
Hi Carsten and all,

 > warning:
test.cxx(18) : warning C4355: 'this' : used in base member initializer list


class A
{
public:
    A() {}
};

class B
{
    A& _a;
public:
    B( A& a ) : _a(a) {}
};

class C : public A
{
    B _b;
public:
    C() : _b( *(A*)this ) {}
};

int main()
{
    C c;
}

Using 'this' in the ctor initializer list can be dangerous, if you don't know what you do. The above example uses a safe way to provide this.

This example does not look too safe to me, because:
It is quite possible that - for example - the maintainer of B one day wants to use a virtual funtion of A that is implemented in C.
And that functionality of B may be called in the constructor body of C.

Pro warning:
In cases like this, generally the maintainer of B has no chance to know that he must not use some functions of A (or C), because the instance of A (or C) is not yet completely constructed.

So the warning is a valid hint to a potential maintainability nightmare.

Contra warning:
The normal workaround would be to move the "this" from the initialization section into the constructor body. This removes the warning, but not always removes the danger, because still the receiver of "this" may use it while not all construction is done.

So one could argue, fixing the warning does not necessarily fix the problem, so we can remove the warning anyway.



I think we have two possible ways to solve this problem.
- Turn of the warning for every occurrence in the code.
- Switch of C4355 for Windows globally.

I'd suggest to take the warning serious and to re-look on each occurrence about this way:

1. Can the construction be re-worked so no self-reference is necessary?
Sometimes this is easy by clarifying a hierarchy that could be a directed graph but currently is a non-directed one.
If yes, do so.

2. If not, is the use of "this" safe including maintainenance in later times?
If yes, see X.

3. If no, make sure there is a comment at all places, using the partly-initialized instance that it may be only partly initialized!
Then goto X.

X. See, if moving "this" from initialization section into c'tor body does any harm. (In case of dialogues, the painting takes so much time, that one could assume, the minor performance drawback of moving the initialisation into the body is negligible - but I don't know that code, so it's just an assumption.)
If yes, do so.
If no, disable the warning locally.


If we just generally disable the warning, we may overlook occurrences where the use indeed is questionable.


Hi Nokolai,

you described a valid problem, but the warning of the compiler is not very smart. It's just triggered by the keyword 'this' in the initializer list. For example the following code also provoke the warning, although it's completely safe to do so:

class A
{
    int _a1;
    int _a2;
public:
    A() : _a1(0), _a2(this->_a1) {}
};

int main()
{
    A a;
}

Using 'this' in the initializer list is not always bad and therefore the warning is in most cases bothersome. Based on my experience with our code I would guess that we probably have a false positive rate >99%. I am afraid that turning on this warning can upset developers as they have to turn off this warning manually for almost all files.

Regards,
Carsten

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to