[Warning] About the object slicing issue...


I was involved in a discussion recently where a beginner fell into the trap of object slicing.

After a quick scan through the Standard and a search on Google I haven’t found anything indicating whether slicing is well-defined or not, though in any case it is always surprising.

I put together a small test file (in attachment) which exposes variations of:

struct B {};

struct V { virtual ~V() {} };

// Constructor
void noslice0(B const& x, B& y, B&& z) {
B a(x); (void)a;
B b(y); (void)b;
B c(z); (void)c;

void slice0(V const& x, V& y, V&& z) {
V a(x); (void)a;
V b(y); (void)b;
V c(z); (void)c;

Using the following command line:

$ clang -fsyntax-only -std=c++0x -Weverything -Wno-missing-prototypes -Wno-weak-vtables slicing.cpp

Clang does not emit any warning for the potential slicing cases (thanks Ted for the discovery mode made easy).

(Note: the test case here intentionally leave out the case where the class has virtual methods but is itself final, or when all methods are final)

I was wondering if there was interest in such a warning ?

There are potentially two approaches, as far as I see it:

Warn on the class declaration whenever it’s usable as a base class (polymorphic + non-final) if the copy/move operators are public

It’s the easiest approach, but is likely to be noisy on unexposed code bases. I don’t like this warning mode for non-virtual destructors already…

Warn whenever a (potentially) slicing conversion occur.

It may be interesting to distinguish between a known occurrence and a potential occurrence (using 2 variants of the analysis/warning)
It may be significantly harder to introduce as a number of expressions may have this issue.

Remarks and opinions welcome :slight_smile:

– Matthieu

slicing.cpp (970 Bytes)