Live data from Hacker News

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

gynvael.coldwind.pl

211–220 of 246 posts

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

#211

Earlier quoted context omitted.

>What is the value of a spec to which compliance is impossible? Are you saying, what's the value of a language spec that allows undefined behavior , as C does? Well, it's that it allows for compiler implementations that aren't too hard to implement and maintain. It allows for a language that's close enough to hardware (and allows you to do programming on a low level), while still offering a reasonable amount of abstr…

> Well, it's that it allows for compiler implementations that aren't too hard to implement and maintain. > It allows for a language that's close enough to hardware (and allows you to do programming on a low level), while still offering a reasonable amount of abstraction to be useful (and usable). I can see the first of these. The second appears to be untrue; if you removed the concept of undefined behavior from C, it…

>The second appears to be untrue; if you removed the concept of undefined behavior from C, it wouldn't get farther away from the hardware

My understanding is that even common CPU instruction sets can have undefined behavior[1].

When C was written, the CPU architectures were more of a Wild West. It might have made sense to leave some parts up to the compiler authors on a particular architecture.

>Is that first point actually something that somebody wants?

When C was written — absolutely.

Portability of C code is almost taken for granted these days.

Things were different then. Portability was a big challenge.

All that said, this is my non-authoritative understanding of the reasons why it's a thing. Take it with a grain of salt.

>At that point, you've given up on having a standard

Sure. Just treat C as a family of languages which have a common standardized part.

Proprietary compiler extensions are/were common anyway, so that's not an unusual situation.

[1] https://www.os2museum.com/wp/undefined-isnt-unpredictable/

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

#212
post #5

The code in the post seems very similar to the one in my own post from 2010: 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 co…

Do you want a job at a place where someone who doesn't understand UB makes the hiring decisions?

In the land of the blind, the one eyed man is King.

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

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

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

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

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

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

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

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

#216

Earlier quoted context omitted.

It'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).

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

That's a valid approach, if you only use high-level language to generate assembly faster, and the assembly is your source of truth.

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

#217

Earlier quoted context omitted.

The compiler does comply to the spec. It's the program that fails to comply with the spec. It's definitely possible to write programs that have no undefined behavior.

The compiler is supposed to compile programs that comply with the spec, and not compile programs that don't. The concept of "compiling a program that doesn't comply with the spec" doesn't even exist! A text file that doesn't comply with the C spec isn't a C program. That's what it means to be "the spec".

> The compiler is supposed to compile programs that comply with the spec

Yes.

> and not compile programs that don't.

No, there is no limitation on what a compiler does in this case.

> The concept of "compiling a program that doesn't comply with the spec" doesn't even exist!

It does, it is called "undefined behaviour".

> A text file that doesn't comply with the C spec isn't a C program.

That's the point. A program that contains UB is not a valid C program. That's what UB means.

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

#218

Earlier quoted context omitted.

Assigning to multiple variables in a single expression is fine and useful. Take ``` target[i++] = source1[j++] + source2[k++]; ``` That's idiomatic, it shows the intent to read and consume the value in a single expression. You can write it longer, but not more clearly. It's only when you assign to the same variable multiple times, or read it after it was assigned, that it introduces ordering issues. A single `i++` or…

>A single `i++` or `++i`/`i += 1` is safe and useful Sure, and you don't need the assignment to be an expression with a value for it to be useful. >target[i++] = source1[j++] + source2[k++]; That's idiomatic That's idiomatic to C for sure. Also idiomatically horrible. Why are you using three index variables here? >You can write it longer, but not more clearly. target[i] = source1[i] + source2[i]; i++; This is absolut…

> Why are you using three index variables here?

> You can't forget to increase one if the indices when all three are meant to go in lockstep.

Obviously they are not in this example.

The next line might contain:

    i++; j *= 42; k = srandom (k), random ();

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

#219

Earlier quoted context omitted.

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

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

Personally, when ever I write a modifying statement, I wonder about the domains of the input and ensure, that the condition necessary to stay in the existing range is evaluated. If it is not, I either write the condition, reduce the input domain, or increase the output domain.

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

#220

Earlier quoted context omitted.

Type punning via unions is not UB in C in general, but it is in C++ IIRC. I write "in general" because, as with other forms of memory reinterpretation (memcpy or copy through a character type), evaluating a trap representation triggers UB.

The short version is that it's fine in C++ as long as you only read the member that was last written to or a char type.

And a slightly longer version is, that there are three types involved: the type of access, the effective type of the object[0], and the type of the variable. The type of the variable is only for the compiler to emit warnings, as long as the effective type and the type of access are equal, it isn't UB.

[0] the C meaning of an object, not the C++ one

Post reply on HN