4

I'm working on some legacy code and I ran into something that I'm not sure is safe - in fact I'm pretty sure it's undefined, but I'm not entirely sure why (more or less a bad feeling).

For some reason this code has a class, we'll call it A. Class A has an overloaded pre-increment operator (++) that appears to do some operations on the value of a pointer contained within it (we'll call that pointer B).

I found a function call where the user passes in A, and a de-referenced copy of pointer B while using the pre-increment operator that's been overloaded.

foo(++A, *B);

Since A's pre-increment modifies the value pointed to by B, and B is dereferenced and used as a parameter in the same call... is there a problem or should I just leave it this way?

Sorry if this sounds confusing - the code is way too complex to paste in but I did my best to explain the situation. If needed, I'll make some fake code representing the situation but I'm hoping its clear.

Also, I'm aware that it's bad design for this code to pass in a parameter already contained in A separately, but I wanted to understand if there was an actual problem aside from that.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255

2 Answers2

7

The order of evaluation of function arguments is unspecified, so if either operation affects the value of the other, then this is indeed a problem.

(In your code, though, this would somehow require B to be a reference to a member of A. As it's written, one would not suspect that there might be a problem (but you noticed this yourself).)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • From the description of the members of `A`, there could be a risk. Since as written it looks OK, that's even worse! – Matt K Nov 29 '11 at 17:16
  • @mkb: Quite - shame on the original author! :-) – Kerrek SB Nov 29 '11 at 17:17
  • 2
    @Pubby: No. It doesn't change the fact that you have two evaluations that are unsequenced with respect to one another. – Kerrek SB Nov 29 '11 at 17:23
  • Thanks, that's what I was looking for. Pubby already addressed my next question, haha - so I'm good now. – John Humphreys Nov 29 '11 at 17:40
  • Actually, what's the difference between unspecified and undefined? Does unspecified mean defined for a specific platform/compiler/etc. but not absolutely defined or something along those lines? – John Humphreys Nov 29 '11 at 17:42
  • @w00te: "unspecified": correct but unpredictable program. "undefined": incorrect program. – Kerrek SB Nov 29 '11 at 17:44
5

The value of parameters is computed before entering the function. The order of computation is not specified. So the code you given might produce unexpected results. You can fix it with

++A;
foo(A, *B)

but of course, as you said if B is part of A then only A should be passed.

Roman Byshko
  • 8,591
  • 7
  • 35
  • 57
  • The order is "defined" (i.e. "what does 'order' mean?"), but not "specified" (i.e. "what is the value of 'order'"). – Kerrek SB Nov 29 '11 at 17:15