Live data from Hacker News

Int a = 5; a = a++ + ++a; a =? (2011)

gynvael.coldwind.pl

231–240 of 246 posts

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#231
post #156

> If you would like to test your compiler (posting back the results in the comments is really appreciated, especially from strange/uncommon compilers and other languages which support pre- / post- increment .... Uh, 85% of them show the wrong result so 85% of them clearly do not support pre and post increment.

If the behavior is undefined, there is no wrong result.

Except that ++a means increment first and a++ means increment after. And that's well-documented and thoroughly understood. Implying that this is undefined behavior is a cop out and cope. Preposterous and juvenile. If not implemented , it should be. Case closed.

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#232

Earlier quoted context omitted.

Genuinely 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 t…

The UB comes from how C++ standard defines expression sequencing which is not relevant for Java. Languages other than C++ typically define such details more strictly so there is no UB or even concept of UB. JIT compilers don't change it as any non toy JIT will generate native instructions directly or through intermediate representation (instead of generating C++ text and passing that through regular C++ compiler) bot…

late to this but what i meant was the JIT Compiler had to be compiled by a compiler at some point so its behavior is defined by the compiler used to compile it (this goes all the way down to the poor soul who hand compiled the first compiler). I'm assuming things like JIT are platform dependent and therefore the compiler used to build it would also be platform dependent. So the JIT on different platforms could have been built from different compilers choosing their own way of handling undefined behavior. ...unless i'm confusing myself which is likely.

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#233
post #209
post #74

Earlier quoted context omitted.

> 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".

I 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.

That 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.

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#234

Earlier quoted context omitted.

> Having an understanding of how the code gets transformed into machine code helps I'm not sure about that. Knowing assembly is not a substitute for knowing how the language is defined. Sometimes C/C++ programmers with some assembly knowledge reason themselves into thinking that what they're asking of the language must have well-defined behaviour, when in fact it's undefined behaviour. It doesn't really matter whethe…

I don't mean assembly in this case, but something more like the compiler's view of the code. a++ can be broken down into more primitive operations, and might actually be, depending on how the compiler is implemented. The fact that the ordering of those more primitive operations with respect to other operations isn't very tightly constrained is something you'd just have to know about the language, I suppose.

> The fact that the ordering of those more primitive operations with respect to other operations isn't very tightly constrained is something you'd just have to know about the language, I suppose.

No, that's not right. It's undefined behaviour, not merely an unspecified order of evaluation. Roughly speaking, the behaviour of the entire program is unconstrained by the language standard after execution of that statement. It could crash the whole process, for instance, or go haywire.

(Again, that's in C, apparently, but not in C++.)

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#235

Earlier quoted context omitted.

I don't mean assembly in this case, but something more like the compiler's view of the code. a++ can be broken down into more primitive operations, and might actually be, depending on how the compiler is implemented. The fact that the ordering of those more primitive operations with respect to other operations isn't very tightly constrained is something you'd just have to know about the language, I suppose.

> The fact that the ordering of those more primitive operations with respect to other operations isn't very tightly constrained is something you'd just have to know about the language, I suppose. No, that's not right. It's undefined behaviour, not merely an unspecified order of evaluation. Roughly speaking, the behaviour of the entire program is unconstrained by the language standard after execution of that statement…

It's worse than that, the behavior of the entire program is unconstrained by the language standard beforehand too. Raymond Chen discusses how things can go wrong once you're going to reach UB even before you get to it: https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...

Anyway, I didn't mean to imply that things behaved as written aside from ordering issues. I only meant that this sort of principle can help you remember where UB lurks. Generally, where a kind C compiler might just mess with your numbers a bit, an evil C compiler can legally make demons fly out of your nose.

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#236

Earlier quoted context omitted.

> 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…

> Except you don't! Except you can do, because "The answer is that this isn't a valid C program." is a sentence you can know.

Syntactically, it is valid. Though yes, semantically it is invalid. Calling it "valid" is going to just continue the same problem because there's multiple ways to interpret valid here

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#237
post #150

Earlier quoted context omitted.

Under what pressure?

Nice I must remember this for the next interview I'm going to attend

Assuming the tennis balls have been digest and shit out by wombat. We thusly have an efficient Cartesian packing ...

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#239

Earlier quoted context omitted.

>Obviously they are not in this example ...of utter insanity which doesn't belong in any real world code. It just keeps getting worse, and shows why it was a horrible idea to allow this in the first place. >The next line might contain: i++; j *= 42; k = srandom (k), random (); Then that's where you do the arithmetic. You're already doing it there, why do you need to do an assignment inside the brackets? (This was a r…

If you only have a single index, that you continue to increment, you don't need an index at all, you just invoke memcpy. It is useful to distinguish between consuming an element and only jumping to it. So you would have an ptr[i++] for consuming the current token, but not, when you are switching to another token. A grouping of index and array modification also provides clarity about the intention. It would read very…

>It is useful to distinguish between consuming an element and only jumping to it. So you would have an ptr[i++] for consuming the current token, but not, when you are switching to another token.

So, it's trivial to do it with a function. Or a macro.

    int adv(int *i){
        int t = *i;
        (*i) = t + 1;
        return t;
    }
    
    while(i 
Not to mention, iterators and all that jazz.

The point is, you don't need assignment to return a value to have this.

Can you give a non-contrived example where you really need it?

>It's obvious that you do prefer the stylistic choices Go made, but that doesn't mean everyone does.

It's not that I "prefer stylistic choices of Go", it's that I hate to have undefined behavior in language spec which is easy to stumble into - the cost of the "stylistic choice" that C made doesn't make that choice justified.

Re: Int a = 5; a = a++ + ++a; a =? (2011)

#240

Earlier quoted context omitted.

> The fact that the ordering of those more primitive operations with respect to other operations isn't very tightly constrained is something you'd just have to know about the language, I suppose. No, that's not right. It's undefined behaviour, not merely an unspecified order of evaluation. Roughly speaking, the behaviour of the entire program is unconstrained by the language standard after execution of that statement…

It's worse than that, the behavior of the entire program is unconstrained by the language standard beforehand too. Raymond Chen discusses how things can go wrong once you're going to reach UB even before you get to it: https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63... Anyway, I didn't mean to imply that things behaved as written aside from ordering issues. I only meant that this sort of principle can he…

> It's worse than that, the behavior of the entire program is unconstrained by the language standard beforehand too. Raymond Chen discusses how things can go wrong once you're going to reach UB even before you get to it

Heh, yes that's exactly what I was thinking when I put roughly speaking.

> where a kind C compiler might just mess with your numbers a bit, an evil C compiler can legally make demons fly out of your nose

Yes, signed integer overflow being another. Presumably it's defined that way as it's simpler than trying to spell out all the behaviours the compiler is permitted to implement, and on top of that there are trap representations to worry about. I doubt modern compilers get much optimization benefit from it though. There's a StackOverflow thread discussing the reasons it's defined this way: https://stackoverflow.com/q/1860461

Post reply on HN