Question: Does the following compile?

int func() { int (func); return func; }

The answer, rather appallingly, is: yes.

The compiler treats the highlighted line as a declaration of an int called func; which is uninitialised.

The compiler allows this, on the grounds that if it looks (vaguely) like a declaration it is a declaration. C++’s Most Vexing Parse is another wonderful example of such behaviour.

On a more practical note this could lead to some very subtle errors in multi-threaded code:

template <typename T> class Monitor { public: void add(const T& in_val) { std::unique_ptr<std::mutex>(mtx); // Acquire the lock // Add the data... } T get() { T out_val; std::unique_ptr<std::mutex>(mtx); // Acquire the lock // Get the data... return out_val; } private: // Some data storage std::mutex mtx; };

This looks OK, but will simply create a temporary std::unique_lock object called mtx – and then discard it. The actual mutex (Monitor::mtx) will never be locked. That is, despite appearances (and no compile errors or warnings), this code isn’t thread-safe.

Good luck debugging this!

A couple of notes on this issue:

This code only compiles because a std::unique_lock has a default constructor. std::lock_guard doesn’t have a default constructor, so this would fail to compile; albeit with a less-than-obvious error.

This problem is far less likely to occur with non-RAII-type classes, because you’ll get an error as soon as you attempt to call any method.

This would fail to compile if you use brace-initialisation.

What’s the moral of this story? Always use brace-initialisation!