You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

The use of incomplete class declarations (also known as "forward" declarations) is common. While it is possible to declare pointers and references to incomplete classes, because the class definition is not available, it's not possible to access a member of the class, determine the size of the class object, and so on. However, it is possible to cast and delete a pointer to an incomplete class, but this is never a good idea.

Non-Compliant Code Example

Consider a common application of a handle/body idiom that implements an abstract data type by a handle that contains a pointer to an implementation class.

class Body; // incomplete class declaration

class Handle {
  public:
    Handle();
    ~Handle() { delete impl_; } // deletion of pointer to incomplete class
    ...
  private:
    Body *impl_;
};

Because impl_ is a pointer to an undefined class, its deletion in Handle's destructor results in undefined behavior if Body has a non-trivial destructor. Even in the case where Body does have a non-trivial destructor, this practice should be avoided. During maintenance a non-trivial destructor could be added to Body, resulting in undefined behavior in the destructor for Handle.

Compliant Solution 1

The deletion of impl_ should be moved to a part of the code where Body is defined.

class Body {
    ...
};

Handle::~Handle() { delete impl_; } // correct.

Compliant Solution 2

Alternatively, an appropriate smart pointer may be used in place of a raw pointer.

class Handle {
  public:
    Handle();
    ~Handle() {} // correct.
    ...
  private:
    std::tr1::shared_ptr<Body> impl_;
};

Note that we used a shared_ptr to refer to the Body. Other common smart pointers, including std::auto_ptr, will still produce undefined behavior.

Risk Assessment

XXX

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR01-A

1 (low)

2 (probable)

2 (high)

P4

L3

References

[[Dewhurst 03]] Gotcha 39: Casting Incomplete Types

  • No labels