3

In this website, in the last section, they have provided f(i = -1, i = -1) as an example of undefined behavior due to unsequenced evaluation of subexpressions within function arguments. But since there is a sequence point after the evaluation of all function arguments and of the function designator, and before the actual function call, f will always be called with (-1, -1) and i will be assigned -1. Is there any possibility of this not happening?

Sourav Kannantha B
  • 2,860
  • 1
  • 11
  • 35
  • Maybe the function changes `i` (a global variable?) – pmg Feb 10 '21 at 12:27
  • 1
    Maybe, but still won't it be defined behavior? Since at the end i will be 'definitely' having value assigned inside 'f' and not -1. – Sourav Kannantha B Feb 10 '21 at 12:29
  • Just to be clear: the comma inside the function call is ***not*** a sequence point. Order of function parameter evaluation is unspecified, so this is indeed UB. – Andrew Henle Feb 10 '21 at 12:33
  • The linked answer has a (slightly contrived) example of what could go wrong. –  Feb 10 '21 at 12:34
  • @dratenik Given today's highly-pipelined CPUs that actually ***do*** execute multiple instructions in parallel, I wouldn't say the example is contrived in any way. – Andrew Henle Feb 10 '21 at 12:36
  • @dratenik exactly... that answer my question. Thank you, and sorry for the duplicate :( – Sourav Kannantha B Feb 10 '21 at 12:36
  • @SouravKannanthaB: The Standard allows implementations to extend the language by specifying how they will behave in situations beyond those mandated by the Standard, especially ones where every implementation to date had behaved consistently. On most platforms, it would cost nothing to treat a write of an object with a value it already holds as a single action with no side effect, but the Standard would allow a compiler to e.g. process each argument by clearing `i` and then decrementing it, and to interleave the operations as "clear i; clear i; decrement i; decrement i;" which in this case... – supercat Feb 10 '21 at 16:46
  • ...would disrupt program behavior. IMHO, quality compilers seek to uphold the principle that if parts of the Standard and an implementation's documentation would unambiguously describe the behavior of some action, but some other parts characterize an overlapping category of actions as Undefined, an implementation should give priority to the former absent a documented and compelling reason for doing otherwise. Unfortunately, some freely distributable compilers have achieved popularity without having to uphold such principles. – supercat Feb 10 '21 at 16:50

2 Answers2

2

... there is a sequence point after the evaluation

Indeed. After the evaluation, so it does no good. The problem here is that there are two unsequenced side effects on i before the sequence point. It's formally UB.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • If there were different values being assigned to i, then it would be undefined since value of i cannot be foreseen... But in this case, i would always evaluate to -1.. Isn't it – Sourav Kannantha B Feb 10 '21 at 12:33
  • @SouravKannanthaB No, the value doesn't matter. Suppose we have some exotic scenario where `i` is a volatile hardware register and every write to it makes something happen in hardware. It is not well-defined if, when or how many times this code will write to that hardware register. – Lundin Feb 10 '21 at 12:36
  • @SouravKannanthaB In a more realistic example, like a mainstream x86 PC compiler, it will likely try to do something seemingly useful out of the situation and very likely just pass along the value -1. But there are no guarantees of any particular behavior, just a quality of implementation issue beyond the scope of the C language. – Lundin Feb 10 '21 at 12:37
1

It's undefined behavior because the standard says it. Modifying a variable without a sequence point between the modifications is UB. There is no "unless both modifications set the same value" exception to the rule.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • So you mean 'with this particular values' this may result in expected behavior, but a similar expression with two different values would result in undefined behavior. Sure... – Sourav Kannantha B Feb 10 '21 at 12:31
  • 2
    @SouravKannanthaB No, it means: "There is no [...] exception to the rule." – Ian Abbott Feb 10 '21 at 12:34