logoalt Hacker News

jstimpfletoday at 10:13 AM1 replyview on HN

Not sure why you're being downvoted. That's completely right. The example is silly. The code is obviously bad, doesn't matter if it's UB or not.

I'm also not convinced (yet) that the example really is UB: I agree reading a volatile is "a side effect" in some sense, and GP cited a paragraph that says just that. But GP doesn't clearly quote that it's a side effect on the object (or how a side effect on an object is defined). Reading an object doesn't mutate it after all.

But whatever language lawyer things, the code is obviously broken, with an obvious fix, so I'm not so interested in what its semantics should be. Here is the fix:

    volatile int x;
    // ...
    int val = x;  // volatile read
    printf("%x %d\n", val, val);

Replies

crotetoday at 11:10 AM

The problem is that the function call as a whole is UB. Having the original example compile to the equivalent of

  volatile int x;
  int a = x;
  int b = x;
  printf("%x %d\n", a, b);
is equally valid as

  volatile int x;
  int a = x;
  int b = x;
  printf("%x %d\n", b, a);
, and neither needs to have the same output as your proposed fix.

C could've specified something like "arguments are evaluated left-to-right" or "if two arguments have the same expression, the expression is [only evaluated once]/[always evaluated twice]". But it didn't, so the developer is left gingerly navigating a minefield every time they use volatile.

show 1 reply