0

I am not really that advanced in C but I found this in a piece of code

ssize_t ret = 0;
ret += sprintf(buf + --ret, "\n");

What does this mean?
And can we really do --ret in this case?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

1 Answers1

7
ret += sprintf(buf + --ret, "\n");

The above line does not mean anything, because it is Undefined Behavior (UB).

Thus, the answer is an emphatic No!.

Why?

Because ret is written twice, and there is no intervening sequence-point.

(The actual increment of ret can happen at any time after reading it to determine the value of --ret, and before the closing semicolon.
Thus, it conflicts with the change by the assignment ret += ....
Also, the read of ret in ret += ... conflicts with the update of ret in --ret.)

As an aside, in C++ since C++11 (sequencing instead of sequence-points) it would be well-defined.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • 2
    This is wrong, or at least incomplete. It's not the typical problem, and someone might reasonably think that since `sprintf(...)` is a function call, there is a sequence point just before a function is called, that the first modification of `ret` happens before that sequence point, and the second modification happens after that sequence point. However, there may be an additional *read* of `ret` before `sprintf` is called, and *that* definitely causes undefined behaviour. Also, unlikely, but in theory `sprintf` might be implemented as a macro that in this case would not have any sequence point. –  Jan 17 '15 at 01:09
  • @hvd: Hm, I updated a bit, just as you wrote that my explanation was a bit thin. Still, are you sure `sprintf` may be a macro? First I heard of that... – Deduplicator Jan 17 '15 at 01:11
  • 1
    Yes, unlike C++, C allows library functions to be implemented as macros, and this was historically commonly done for functions such as `isupper`. It's extremely unlikely to be done for `sprintf` though. See 7.1.4: "[...] Any function declared in a header may be additionally implemented as a function-like macro defined in the header, [...]" –  Jan 17 '15 at 01:14
  • @hvd: I'm sure I must have read that sometime... Thanks, I'll try to remember that from now on. – Deduplicator Jan 17 '15 at 01:16
  • 1
    Thanks @Deduplicator and hvd for taking My question seriously And sorry if I didn't give enough code but I did understand the hole code its this line that got me ,and the weird thing is that when I use standard GCC compiler it compile without errors ,but when II cross compile for arm processors it show the forbidden operation error ,now the problem is solved thanks to you two ,can you point me how to make this as solved ? – Rachid Boudjelida Jan 18 '15 at 08:06
  • @LôrdRalfAdolf: The way to mark things as "solved" (in the askers opinion, he might be wrong), is accepting the answer which helped him best understand. If neccessary, that might be taking all the hints in comments and writing and accepting a self-answer (which depending on own contributions, should *sometimes* be marked community-wiki). Later, when you gained the privilige, you can thank others for valuable contributions by upvoting their answer (though *please* not just for effort). – Deduplicator Jan 18 '15 at 14:43