6 ms·
IMO, The only reasonable answer if asked this in an interview is “I would not write code where I have to know the answer to this question” These sorts of thing
by kentm 5mo ago
IMO, The only reasonable answer if asked this in an interview is “I would not write code where I have to know the answer to this question”
These sorts of things are neat trivia to learn about things like sequence points but 99.9% of the time if it matters in your codebase you're writing something unmaintainable.
- tzs 5mo ago> IMO, The only reasonable answer if asked this in an interview is “I would not write code where I have to know the answer to this question” That's half of a reasonable answer. The other half is "but I do know the answer so if I see it when reviewing or working on someone else's code I can flag it or rewrite it, and explain to them why it is bad".
- amelius 5mo agoYou might still make a mistake, even if you think you know the answer. It's much better to instrument the code to figure it out, or write a short test program.
- bestouff 5mo agoIt's Undefined Behavior. So you can instrument all you want, the answer will still be wrong. You'll capture what your particular compiler does under some particular conditions (opt flags, surrounding code, etc.) but that will not be representative of what can happen in the general case (hint : anything can happen with UB).
- amelius 5mo agoIt doesn't matter if the answer is wrong. You run the test program and then replace the code by the answer. This basically weeds out the UB.
- yongjik 5mo agoBut since it is a UB, there's no guarantee that your test program produces the same result as the same code running on production, even if you have the same compiler.
- amelius 5mo agoThat's very unlikely, and in the worst case you've reduced a difficult bug into an easier to understand bug.
- 1718627440 5mo agoThat's a valid approach, if you only use high-level language to generate assembly faster, and the assembly is your source of truth.
- thaumasiotes 5mo ago> It's Undefined Behavior. Susam's post doesn't make this clear. The quotes from K&R say that the modifications to the variable may take place in any order, but they don't directly say that doing this is Undefined Behavior, which would make it permissible to do anything, including e.g. interpreting the increments as decrements. The C99 standard is quoted saying this: >> Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. It's possible that something else in the standard defines noncompliance with this clause as Undefined Behavior. But that's not the most intuitive interpretation; what this seems to say, to me, is that the line of code `a = a++ + ++a` should fail to compile, because it's not in compliance with a requirement of the language. Compilers that produce any result at all are suffering from a bug. (It seems more likely that the actual intent is to specify that, given the line of code `b = a++ + ++a`, with a initially equal to 5, the compiler is required to ensure that the value stored at the address of a is never equal to 6 - that it begins at 5, and at some indefinite point it becomes 7, but that there is no intermediate stage between them. But I find the 'compiler failure on attempt to put multiple modifications between two sequence points' interpretation preferable.)
- Dylan16807 5mo agoCompilers are not able to prevent you from violating must/shall in the general case. So they're not held to that bar. Unless the standard says not to compile it, it's not a compiler bug. Also, imagine a situation where the line of code actually lists three different variables, but all three of them are passed in by address. It quickly becomes impossible for the compiler to know you violated the spec by reusing the same variable. And even optimizations that make sense here could corrupt the value pretty badly and possibly lead to worse errors.
- thaumasiotes 5mo ago> Also, imagine a situation where the line of code actually lists three different variables, but all three of them are passed in by address. It quickly becomes impossible for the compiler to know you violated the spec by reusing the same variable. OK. What is the value of a spec to which compliance is impossible?
- tengwar2 5mo agoNot nasal demons in this case (https://groups.google.com/g/comp.std.c/c/ycpVKxTZkgw/m/S2hHdTbv4d8J https://groups.google.com/g/comp.std.c/c/ycpVKxTZkgw/m/S2hHd...): thaumasiotes shows that we can expect a numeric answer.
- _kst_ 5mo agoI don't see the name "thaumasiotes" at that link, nor do I see anything relevant to the code in the title. The behavior of "int a = 5; a = a++ + ++a;" is undefined. There is no guarantee of a numeric result, because there is no guarantee of anything.
- susam 5mo agoI believe they were referring to thaumasiotes's thread here: https://news.ycombinator.com/item?id=48141294 https://news.ycombinator.com/item?id=48141294 I think the objection thaumasiotes has raised there is valid and I have made an attempt to answer it as well in the same thread.
- HarHarVeryFunny 5mo agoIt's only the order of evaluation that is undefined.
- afdbcreid 5mo agoNope, there is no sequence point in the middle and modifying an object more than once between sequence points is undefined behavior.
- _kst_ 5mo agoNo, the behavior is undefined. That means, quoting the ISO C standard, "behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this document imposes no requirements". A conforming implementation could reject it at compile time, or generate code that traps, or generate code that set a to 137, or, in principle, generate code that reformats your hard drive. Some of these behaviors are unlikely, but none are forbidden by the language standard.
- IshKebab 5mo agoNo it isn't. You don't need to know the answer to know that it is bad code. The very fact that it isn't clear shows that.
- tialaramex 5mo agoRight, the feedback I'd expect in a code review interview is something like "This is unclear or wrong, write what you actually meant". That's the feedback I would want, and it's the feedback I give to my colleagues in reviews. Actually I tend to be too verbose, so you might get a full paragraph explaining what the ISO document says and that you shouldn't assume it does whatever it is your compiler says. My actual feelings for this specific case are that the language is defective, but if we're wedded to a defective language then the reviews need to call out such usage.
- godelski 5mo ago> Actually I tend to be too verbose, so you might get a full paragraph explaining what the ISO document I'm verbose too, but I love it when others are. Honestly, it's usually easy to triage (and I write to try to make it easy). I like verbosity because learning why means I not only won't make that mistake again but I won't make any similar mistakes again. Verbosity isn't bad. Not everything needs to be a fucking tweet
- 1718627440 5mo agoIf you know is this code is bad, but don't know that it is UB, I thing you are rating code on feelings and cargo culting.
- godelski 5mo ago> The other half is "but I do know the answer Except you don't! If you claim to know the answer you've made a grave mistake and fooled yourself. If you ran the code in a compiler and used that to conclude "this is the answer" rather than "this is an answer" then now is a great time to learn how easy it is to fool yourself. You just need you ask yourself what assumptions you made. I'll wager you assumed all compilers process this line in the same way. Or just RTFA, or Susam's, as that's exactly what they are about. They explain why this is undefined behavior. | The first principle is that you must not fool yourself — and you are the easiest person to fool. - Feynman
- tzs 5mo ago> I'll wager you assumed all compilers process this line in the same way You would lose that wager. What I mean by "I do know the answer" is that I know that this is undefined behavior and why it is undefined behavior and that different compilers can give different results and also that even if I test the compiler I use to see what it does I can't count on that not changing any time the compiler gets updated.
- godelski 5mo agoFair, but that was not clear to me that that's what you meant. It's clear that others interpreted it the way you intended too (since there are multiple replies saying exactly what you said) but I also don't think I'm the only one who misinterpreted. Sorry that I did.
- fyolnish 5mo agoSeems fitting in a thread about undefined behavior
- benj111 5mo agoI think you're misinterpreting "I know the answer". The GP is suggesting rewriting it, so the know the issue.
- 1718627440 5mo ago
- atoav 5mo agoI mean the good answer is: I am not sure this code could be interpreted the same by different programmers and compilers alike. So I would never write it.
- MaxBarraclough 5mo agoThat isn't a strong answer, unless the question was about what you think of the code's style. The point is that it's more than just poor style, it's likely to constitute undefined behaviour. Saying different compilers could interpret the expression differently is not equivalent to saying it invokes undefined behaviour. It's common for interview questions to explore unusual code, perhaps poor quality code, that hinges on edge cases of the language. A candidate with a strong understanding of the language would be expected to take the opportunity to demonstrate it.
- zeroq 5mo agoOn one hand I've been using almost the exact statement 25 years ago in my Flash (ecmascript) tutorials to narrow down the point of operator precedence. I still believe it's a good piece on your powerpoint if you want to teach. It's easy to fall, easy to grasp, and easy to unroll all the rules - that is, if the rules are actually set in stone. On the other hand I've been through couple FAANG interviews, and twice I was presented with something similar and after I glanced at it for a half a minute the interviewer quickly proceed to "a ha!, you don't know! the interview is over , but I'm happy to tell you the right answer". That part is not cool.
- adrian_b 5mo agoThe answers to some questions must be known in order to be able to write a correct program. In the vast majority of the programming languages, the order of evaluation for the actual parameters passed to a function is undefined. In the few programming languages where the order of evaluation is defined, that is actually a mistake in the design of that programming language. This is something about which any programmer must be well aware, because when composing function invocations it is very easy to write a function invocation where the result would depend on the order of evaluation of the expressions passed as actual parameters. The arithmetic operators are also function invocations, so that applies to them too.
- chii 5mo ago> when composing function invocations it is very easy to write a function invocation where the result would depend on the order of evaluation of the expressions passed as actual parameters this simply means your functions aren't pure functions, and is doing side effects. If you rewrite those functions to not have side effects (including ones being used to generate the parameters), there would be zero issues of such nature.