9 ms·
The code in the post seems very similar to the one in my own post from 2010: https://susam.net/sequence-points.html https://susam.net/sequence-points.html in
by susam 5mo ago
The code in the post seems very similar to the one in my own post from 2010: https://susam.net/sequence-points.html https://susam.net/sequence-points.html
int a = 5;
a += a++ + a++;
I do remember that this particular code snippet (with a = 5, even) used to be popular as an interview question. I found such questions quite annoying because most interviewers who posed them seemed to believe that whatever output they saw with their compiler version was the correct answer. If you tried explaining that the code has undefined behaviour, the reactions generally ranged from mild disagreement to serious confusion. Most of them neither cared about nor understood 'undefined behaviour' or 'sequence points'.
I remember one particular interviewer who, after I explained that this was undefined behaviour and why, listened patiently to me and then explained to me that the correct answer was 17, because the two post-increments leave the variable as 6, so adding 6 twice to the original 5 gives 17.
I am very glad these types of interview questions have become less prevalent these days. They have, right? Right?
- colechristensen 5mo ago>I am very glad these types of interview questions have become less prevalent these days. They have, right? Right? I just refuse to do interviews like that any more.
- kentm 5mo agoIMO, 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
- 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.
- LPisGood 5mo agoIn some sense, and without the interviewer knowing, that is actually a great scenario for an interview. If you can convince someone in a position of authority that they’re wrong about something technical without upsetting them then you’re probably a good culture fit and someone who can raise the average effectiveness of your team.
- rcxdude 5mo agoOr, also, in the reverse direction, if the interviewer is wrong about it and can't be convinced otherwise, it's probably not a great place to work.
- bluGill 5mo agoI know I did recommend someone after the interview because I looked it up and they were right. Great person to work with. Though I fully understand why most would hesitate.
- wat10000 5mo agoThe best interview questions spawn discussions. This is a pretty good one for that. We could dive into what makes it UB, why a particular compiler might do it a certain way, what results we'd likely see from other compilers, and why the standard might say that this sort of thing is UB. "What does this produce?" and expecting an answer of "17" is a bad question even if UB didn't mean the expected answer is wrong.
- LPisGood 5mo agoI don’t work a ton with C, but I wonder how C programmers keep track of what behavior is and is not defined. It seems like there are many possible edge cases.
- wat10000 5mo agoWe get by on a combination of matching patterns (any pointer cast gets a lot of scrutiny, for example), compiler warnings, tools like UBSan, debugging when things go wrong, and sheer dumb luck. Having an understanding of how the code gets transformed into machine code helps. For this case, there's the basic idea that `a++` will boil down to three basic conceptual operations: fetch, add, and store, and those can be potentially interleaved with other parts of the statement. In something like `a++ + ++b` the interleaving doesn't affect the outcome no matter how it's done. In `a++ + ++b` the interleaving can affect the outcome, and that's your sign that something might be wrong. Any memory safety issue in C code had to involve UB at some point. And you can see how prevalent those are, and deduce how not-particularly-great we are at keeping track of UB.
- mike_hock 5mo agoDo you want a job at a place where someone who doesn't understand UB makes the hiring decisions?
- grahamburger 5mo agoSometimes, even in tech, you just need a job.
- ketzu 5mo agoI think your options are very limited if you look for places that have people that truly understand UB, even less so the hiring people.
- angry_octet 5mo agoIn the land of the blind, the one eyed man is King.
- mike_hock 5mo agoAnd I thought he was just a senator.
- p0w3n3d 5mo agoHow many tennis balls can fit in a bus?
- genxy 5mo agoUnder what pressure?
- chii 5mo agoobviously under the maximum allowable pressure that each surface of the bus can withstand.
- p0w3n3d 5mo agoNice I must remember this for the next interview I'm going to attend
- genxy 5mo agoAssuming the tennis balls have been digest and shit out by wombat. We thusly have an efficient Cartesian packing ...
- SilasX 5mo agoHeh, one time when I got this style of question[1] (but for JavaScript), I took a glance at it and said "Um ... you really shouldn't write code like that." The interviewer replied, "Oh. Yeah. Fair point." And then went on to another question. [1] By which I mean predicting the behavior of error-prone code that requires good knowledge of all the quirks of the language to correctly answer.
- tete 5mo ago> I found such questions quite annoying because most interviewers who posed them seemed to believe that whatever output they saw with their compiler version was the correct answer. Other than the job for most programmers having nothing to do with whether they know the outcome, because hopefully they'd never write something like it or clean it up. And IF they found it they'd hopefully test it - given that it appears to be compiler dependent anyways.
- thaumasiotes 5mo ago> I am very glad these types of interview questions have become less prevalent these days. They have, right? Right? Are you referring to the type of interview questions where the question is ill-defined and no one should know the answer, or the type where the question is reasonable and well-defined, but the interviewer doesn't know the answer? I had a phone screen with Google once where they asked how to determine the length of a stretch of contiguous 1s within an infinite array of 0s. I suggested that, given the starting index i, you can check the index i+2 and then repeatedly square it until you find yourself among the zeroes, after which you can do binary search to find the transition from ones to zeroes. The interviewer objected that this will grow the candidate end index too quickly, and the correct thing to do is to check index i+1 and then successively double it until you find the zeroes. We moved on. I passed that phone screen. But I still resent it, because I checked the math later and "successive squaring followed by binary search" and "successive doubling followed by binary search" take exactly the same amount of time.
- susam 5mo agoI meant the latter. I think the question is fine. It can lead to a good discussion, similar to what we are having in this thread. It has been a long time (almost 20 years), but I remember that most interviewers who asked this seemed to be convinced that the output they had seen with their compiler version was the correct answer. What could be a nice and relevant discussion, especially considering that some classes of bugs and security issues result from it, was seen only as a trivia quiz by the interviewers, with the expectation of an answer that was incorrect, no less. Your phone screen story is quite nice. When I read your question, I would have answered with successive doubling as well. In fact, I faced the same question at an AWS interview a long time ago. The question was mathematically the same question but formulated differently. I answered with the doubling solution too, which leads to an O(log n) time solution, asymptotically. Your interviewer's immediate objection to your squaring solution seems like a major failure in their intuition. When I read your solution, purely by intuition, that is, without resorting to any rigorous reasoning, I felt: wow, that's interesting, your solution would land on the zero region in merely O(log log n) time. Why didn't I think of it? I think your solution should spark interest rather than dismissal in a curious person. Of course, the binary search after that to find the exact transition point blows up the time consumed back to O(log n). Once again, thanks for these really interesting comments!
- chasd00 5mo agoGenuinely curious, so this is undefined behavior and depends on the compiler. I get that. Java, and other languages, can do these same operations but their compilers produce bytecode that runs on a virtual machine (JVM) compiled to machine code just-in-time. Would this same code in Java possibly yield different results based on the platform the JVM was running on because of the platform specific JIT compiler? Maybe that's part of the origin of the phrase "write once, test everywhere".
- dmoy 5mo ago> Would this same code in Java possibly yield different results based on the platform the JVM was running on because of the platform specific JIT compiler? No, and it's also well defined in languages like C#. If we're talking about this specific example at least. No sequence point issues like that in Java.
- Crespyl 5mo agoIt's been quite a while, but IIRC, in Java these statements actually do have a defined behavior. The ++x is a "pre-increment", meaning the value of the variable is incremented prior to evaluating the expression, while the "post-increment" "x++" is the other way around: the expression evaluates to x, then x is incremented afterwards. All expressions are left-to-right.
- tredre3 5mo agoThat behavior is inherited from C. The pre/post increment behavior is actually the same in every language that uses them. The priority of operation is also usually the same as well. The reason the question is tricky is because those operators change the value of a as the full expression is progressively executed. It's not immediately clear to me what the answer in Java would be. Just take a++ + ++a for example: If the value if `a` is hoisted by the jvm then it could be 5++ + ++5, so 5 + 6. But if it's executed left to right and `a` is looked up every time, then it becomes 5++ + ++6, so 5 + 7.
- deleted 5mo ago[deleted]
- vcdk 5mo agoWell... tried it on macOS using vanilla gcc, the results surprised me: $ /bin/cat x.c; gcc -w -o x x.c; ./x #include <stdio.h> int main() { int a = 5; a += a++ + a++; printf("a = %d\n", a); } a = 18 Not what I expected. This must be how it works: - The first a++ expression results in 5, after a = 6 - The second a++ expression results in 6, after a = 7 - Only then the LHS a is evaluated for the addition-assignment, so we get: a = 7 + 5 + 6 = 18
- jcalvinowens 5mo agoBoth major compilers yell at you for this nowadays... it's pretty unforgivable IMHO for somebody to be asking it as an exam or interview question if the right answer isn't "undefined": <source>:5:10: warning: multiple unsequenced modifications to 'a' [-Wunsequenced] 5 | a = a++ + ++a; | <source>:5:7: warning: operation on 'a' may be undefined [-Wsequence-point] 5 | a = a++ + ++a; | ~~^~~~~~~~~~~
- everyone 5mo agoThe interviewer asking stuff like that is a good sign to leave immediately.