1

I'm facing a peculiar question today..

What happens when I use the prefix increment on a variable inside a function parameter list, but then reuse that variable again in the parameter list? Will the prefix increment happen before the variable gets evaluated as part of the second parameter?

(And I suppose I might as well ask, what if one were to use a postfix increment instead?)

Example(++marker1, marker2 - marker1);
jramm
  • 751
  • 1
  • 8
  • 26
  • You could always try it and see... – jez Oct 08 '14 at 02:34
  • @jez: That will tell you what one particular compiler does. But it won't tell you that the result is unspecified. – Mike Seymour Oct 08 '14 at 02:38
  • Short answer: Don't do that. – Neil Kirk Oct 08 '14 at 02:40
  • 2
    I think this is the [C++ canonical UB question](http://stackoverflow.com/q/4176328/1708801) although it is kind'a lousy for this question, can't find a more specific one. The C version that covers this is [this one](http://stackoverflow.com/q/376278/1708801) the logic is almost identical pre C++11. – Shafik Yaghmour Oct 08 '14 at 02:52
  • @MikeSeymour definitely UB in C++11, [please see live example](http://coliru.stacked-crooked.com/a/8d726ccf44f32bd9) with warning: *unsequenced modification and access to...* – Shafik Yaghmour Oct 08 '14 at 02:59
  • @ShafikYaghmour: Sorry, you're right. I was mixing up the argument evaluation (unsequenced) and parameter initialisation (indeterminately sequenced). It is UB. – Mike Seymour Oct 08 '14 at 03:01
  • @MikeSeymour np, I answer UB question all the time and especially in C++11 I always have to stop and think about it to make sure I have it right. – Shafik Yaghmour Oct 08 '14 at 03:04

1 Answers1

3

The evaluation of the function arguments is unsequenced, so modifying a variable in one and using its value in another gives undefined behaviour. That's the case whether you use pre-increment or post-increment.

In general, avoid modifying a variable as part of a complicated expression; especially if its value is used elsewhere in the expression, since that tends to give an unspecified value or (in some cases) undefined behaviour.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Any reason for the downvote? I'm fairly sure this is correct. – Mike Seymour Oct 08 '14 at 02:41
  • can you name any compiler that does not evaluate from left to right? – Aditya Singh Oct 08 '14 at 02:42
  • @Aditya: No, I'n not that familiar with any compiler's impelementation details. How does that change the fact that the order is unspecified? – Mike Seymour Oct 08 '14 at 02:44
  • @Aditya [this defect report](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#430) shows at least one case, there may be others. The evaluation of the arguments to the function are indeterminately sequenced relative to one another and the compiler is free to evaluate them in any order. – Shafik Yaghmour Oct 08 '14 at 02:47
  • but as a convention most of the famous comilers use left to right evaluation and thats what i mentioned. may it be gcc compiler, borlands turbo comiler or microsofts compiler. – Aditya Singh Oct 08 '14 at 02:48
  • @ShafikYaghmour: At least since C++11, they are sequenced; but indeterminately so. (Possibly they were unsequenced before then; I don't have any historic standards to hand.) – Mike Seymour Oct 08 '14 at 02:48
  • Correct, that is what I meant to say, pre C++11 the standard used sequence points and more than one modification within a sequence point or a modification and an access other than to determine the previous value was UB. – Shafik Yaghmour Oct 08 '14 at 02:50
  • @Aditya: What does fame have to do with anything? The order is unspecified, so can't portably be relied on. I certainly wouldn't want my code's correctness to depend on which compiler I happen to be using. – Mike Seymour Oct 08 '14 at 02:50
  • yeah thats right. but as you said just now as of cpp11, the order has been specified. so i will edit my answer too. – Aditya Singh Oct 08 '14 at 02:51
  • 1
    @Aditya: No, I didn't say the order has been specified in C++11. To quote the standard: "Such initializations are **indeterminately sequenced** with respect to each other". So they are sequenced (i.e. one has to be completely evaluated before another starts), but the order isn't specified. – Mike Seymour Oct 08 '14 at 02:53
  • In fact, it's worse than that, since I was mixing up the argument evaluations with the parameter initialisations. "The evaluations of the argument expressions are all **unsequenced** relative to one another", so it's undefined behaviour, not just an unspecified result. – Mike Seymour Oct 08 '14 at 03:09
  • @MattMcNabb: Indeed, I've corrected the answer. I thought the argument evaluations were (indeterminately) sequenced when I wrote it; now I've learnt that's not the case. – Mike Seymour Oct 08 '14 at 04:13