views:

191

answers:

3

Years ago I believed that C was absolutely pure compared to C++ because the compiler couldn't generate any code that you couldn't predict. I now believe counter examples include the volatile keyword and memory barriers (in multiprocessor programming or device drivers for memory-mapped hardware devices, where plain assembly language would be even more pure than the optimizations of a C compiler).

At the moment I'm trying to enumerate the unpredictable things a C++ compiler can do. The main complaint that sticks in my mind about C++ is that the compiler will implicitly instantiate temporary objects, but I believe these cases can all be expected. The cases I'm thinking of are:

  • when a class defines a copy constructor for a type other than itself, without using the explicit keyword
  • when a class defines an overloaded conversion operator: operator ()
  • when a function accepts an object by value instead of by reference
  • when a function returns an object by value instead of by reference

Are there any others?

+2  A: 

I suppose "unpredictable" means "something in accordance with the standard but different from what the programmer expects when writing code", right?

I guess you can see from the code where objects are being instantiated or copied, even if it's maybe not obvious. It might be hard to understand though.

Some stuff is just implemented in certain ways by (all?) compiler vendors, but it could be done differently. E.g., late binding (aka. calling an overloaded, virtual method) is usually implemented using function pointers in the background. This is maybe the fastest way doing it, but I suppose it could be done differently and that would be unexpected. I don't know any compiler though that does it differently.

Lots of stuff is unexpected in the sense that C++ is overly complex - hardly anybody understands the full language. So unexpected also depends on your knowledge.

+1 for a good analysis of what seems to be the problem in understanding the question.
Christopher Creutzig
+2  A: 

12.2 Temporary objects

1 Temporaries of class type are created in various contexts: binding an rvalue to a reference (8.5.3), returning an rvalue (6.6.3), a conversion that creates an rvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5).

4 There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.

In fact I suggest take a look at the entire 12.2

At the moment I'm trying to enumerate the unpredictable things a C++ compiler can do. The main complaint that sticks in my mind about C++ is that the compiler will implicitly instantiate temporary objects, but I believe these cases can all be expected.

The compiler does not create temporaries implicitly -- it obeys the standard. Unless, of course, when you invoke undefined behavior. Note, that there is something called copy-elision and return value optimization which may actually reduce the number of temporaries that would otherwise be created.

dirkgently
A: 

An interesting link about common pitfalls related to this subject:

http://www.gotw.ca/gotw/002.htm

loic