5 ms·
Just read the email.
by DanWaterworth 11y ago
Just read the email.
- zzalpha 11y agoActually it's still a useful question, I think. A simple example is function argument evaluation order. If you have: foo(bar(), baz()) A compiler is free to call these functions in either order. That means if baz relies on state mutated by bar, the program may behave differently if the compiler chooses to reorder evaluation.
- tedunangst 11y agoA perhaps more interesting, quite realistic example: lock_two_widgets(widget *a, widget *b) { if (a < b) { lock(&a->lock); lock(&b->lock); } else { lock(&b->lock); lock(&a->lock); } }
- just_curioussss 11y agoIf lock calls include a memory barrier, which they should, then they cannot be reordered. Edit: Your code has undefined behavior, unless the two pointers point to the same object, which is unlikely in a realistic example.
- ufo 11y agoYes, the pointer comparison is UB but if the compiler didn't go out of its way to screw you over UB code then it would be a reasonable way to prevent deadlock.
- just_curioussss 11y agoThere is a defined method for comparing such pointers. Take unsigned char pointers to them and inspect their bytes. Then write your code, using that information, that does the comparison, assuming you know your architecture. It is defined behavior to read the bytes of any object using unsigned char.
- kbwt 11y agoAlternatively, if the implementation supports uintptr_t, you can convert to that and then compare the respective integral values.
- DanWaterworth 11y agoRight, because you can get to the end of a non-void function without producing a value. The pointer comparison isn't necessarily UB.
- copsarebastards 11y agoThere's a parable where a man goes to the doctor and says, "Doctor, whenever I drink my coffee with the spoon in the cup, the spoon handle pokes me in the eye and it hurts." And the doctor says, "Well, stop doing that." If you wrote `foo(bar(), baz())` and `baz()` relies on state mutated by `bar()`, your code is bad, and you should feel bad, because experiencing those bad feelings is the way you learn to not write bad code. This code was wrong before the compiler reordered the calls, it just failed silently for a while. The compiler isn't responsible for fixing your bugs, you are. People need to stop expecting other people to fix their problems.
- snarfy 11y agoIf bar() returned the mutated state, he could just do: foo(baz(bar()))
- copsarebastards 11y agoI think a better design would be to separate mutators from pure functions. If a procedure mutates state, it should have a void return type, and if a procedure returns a value it should be a pure function that doesn't mutate state. This is, of course, a rule of thumb, not a hard law. Some exceptions: 1. I think it's okay (and in fact, idiomatic in C) to mutate state and return some sort of information about what occurred (i.e. a success flag, a number of characters written, etc.). 2. Isolated mutations such as logging sometimes make sense in an otherwise pure function.
- snarfy 11y agoI'm a fan of fluent design myself, and dislike flags. return foo().baz().bar(); With flags you start with success/fail, and end up with HRESULT.
- copsarebastards 11y agoI'd agree with you in some languages, but in C this would be prohibitively difficult. In general, good fluent design uses immutable objects, which makes it basically just a syntactic sugar for functional programming. While fluent syntax is nice, the functional semantics are the real value, and are much easier to do in C (although, as soon as you add in memory management, functional programming often becomes prohibitively difficult too).
- just_curioussss 11y agoThat is called unspecified behavior not undefined behavior. Major difference.
- mlvljr 11y agoNot many know (and less people care), funnily :) I have yet to see a thorough (source-to-compiler-intent-to-assembly) comparative description of undefined, unspecified and implementation-defined behaviors, though (not just a somewhat insightful blog, or techno gospel, which the C and C++ standards are).
- nitrogen 11y agoYou could always write one. I recommend the work of John Regehr as a starting reference: http://blog.regehr.org/ http://blog.regehr.org/
- mlvljr 11y agoI wish I had time to learn this first :) But yes, authoring a book titled "Well-defined C (and C++)" one day would be awesome. Thanks for the link.