Live data from Hacker News

So you think you know C? (2016)

wordsandbuttons.online

171–180 of 344 posts

Re: So you think you know C? (2016)

#172

> Eventually, I had to learn to rely on the standard instead of folklore; to trust measurements and not presumptions... Indeed, testing your assumptions, because even a defined standard may result in a differing implementation of it. Especially in critical applications, testing the expectations gives some sense of a defined behavior. This quizz is amusing as a mental exercise and a parable, but in reality all of thes…

Just to flesh this out, I put the puzzle code through gcc 6.3, on ideone

https://ideone.com/PziSzq

Result:

1:8 2:0 3:-96 4:1 5:2

Sure, there's a bunch of warnings emitted... fortunately.

Re: So you think you know C? (2016)

#175

Having written a conforming C compiler, at one point I knew everything there was to know about C (I forget details now and then, or confusing them with C++ and D). But knowing every engineering detail is not the same thing as knowing how to program in C effectively. It's like being the engineer who designs a Grand Prix car. It does not mean you can drive it faster around the track than anyone else. Not even close. Fo…

Strong agreement here.

You can limit yourself by choice to certain areas of the language that you know inside out (you know the asm they produce, etc.) and use it to solve problems. Don't worry about every single corner case. As you said, you can easily forget those things, especially if it's not your day-to-day job.

The same idea and principle can be found in "JavaScript - The Good Parts".

Re: So you think you know C? (2016)

#176
post #53

I found it an amusing excrcise, if not terribly relevant, even as someone who spends 90% of his dev time in C. What rubs me about these sorts of articles is they make some presumption about the importance and nessecisity of writing truely portable C, as if the "C Standard" were in and of itself a terribly useful tool. This is in contrast to where I live most of the time which is "GCC as an assembler macro language" (…

It's very much worth reading, Linus Torvalds' opinion of standards that's linked in that article, but I'll link it again here: https://lkml.org/lkml/2018/6/5/769 "So standards are not some kind of holy book that has to be revered. Standards too need to be questioned." The way I see it, a lot of compiler writers are basically taking the standard as gospel and ignoring everything else "because the standard doesn't say…

This is a common misconception. Compiler authors don't exploit undefined behavior to make themselves seem smart, or because they like breaking code. They exploit undefined behavior because somebody filed a bug saying some code was slow, and exploiting UB was the simplest way--or, in many cases, the only way--to fix the performance problem.

GCC and Clang do give you the option to avoid optimizations based on undefined behavior: compile at -O0. We think of the low-level nature of C as being good for optimization, but in many cases the C language as people expect it to work is at odds with fast code.

It's fascinating to actually dive into the specific instances of undefined behavior exploitation that get the most complaints. In each such case, there is virtually always a good reason for it. For example, treating signed overflow of integers as UB is important to avoid polluting perfectly ordinary loops with movsx instructions everywhere on x86-64. It's easy to see why compiler developers added these optimizations: someone filed a bug saying "hey, why is my loop full of movsx", and the developers fixed the problem.

Edit: Should be movsx instead of movzx, sorry.

Re: So you think you know C? (2016)

#177
post #146

Earlier quoted context omitted.

> Compile it, look at the assembly. You can know. The answer will vary from place to place, but it isn't non-existent. This pretty much is the definition of "undefined behaviour" in the context of a standardized language specification.

Whoa there! You mean “unspecified behavior”. int i = [unspecified] means that i has some value, but the spec doesn’t determine the value. Undefined behavior means that all your secrets might be sold to the highest bidder, your centrifuges might explode, and your computer is now full of ransomware.

Whilst my other comment was intended to be jovial, it is hard to say if that was accurately conveyed. So this one will be serious.

The original problem definition, as specified by @pksadiq, read thusly:

> Say for example, in question 5, the statement "return i++ + ++i;" is undefined ...

This inspired a response by @Filligree of:

> Compile it, look at the assembly. You can know. The answer will vary from place to place, but it isn't non-existent.

Given the original constraint of an undefined statement result, and the suggested activity to address same, I posited that the recommended action is an exemplar of observing the product of undefined behaviour.

You then contributed:

> You mean “unspecified behavior”.

As per c-faq.com[0], there are three categories identified relating to this topic:

1 - implementation-defined: The implementation must pick some behavior; it may not fail to compile the program.

2 - unspecified: Like implementation-defined, except that the choice need not be documented.

3 - undefined: Anything at all can happen; the Standard imposes no requirements.

Whereas you imply a standards-conformant implementation of "return i++ + ++i;" is unspecified (category #2), it is, in fact, undefined (category #3). The support for this assertion is as follows.

As per the same site, Question 3.8[1] includes:

> Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.

And further states:

> ... if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written. This rule effectively constrains legal expressions to those in which the accesses demonstrably precede the modification.

And concludes with an example stating:

> ... the Standard declares that it is undefined, and that portable programs simply must not use such constructs.

Therefore, the original expression presented by @pksadiq is in fact an exemplar of an undefined expression as defined by category #3 shown above. Since both it and the message to which I originally responded satisfy same, I stand by my response given to @Filligree as having had informally defined the standard C concept of "undefined behaviour."

0 - http://c-faq.com/ansi/undef.html

1 - http://c-faq.com/expr/seqpoints.html

Re: So you think you know C? (2016)

#178

Having written a conforming C compiler, at one point I knew everything there was to know about C (I forget details now and then, or confusing them with C++ and D). But knowing every engineering detail is not the same thing as knowing how to program in C effectively. It's like being the engineer who designs a Grand Prix car. It does not mean you can drive it faster around the track than anyone else. Not even close. Fo…

And that's why people claiming that C++ is more complicated than C because it has an even bigger specification miss the point.

What counts is how easy to use in practice. You can get along just fine in C++ without knowing the exact aliasing rules from C or or how to specialize a template. What matters is that the extra features of C++ makes actual programming simpler, not harder. (for example destructor (RAII), standard library, classes, ...)

Re: So you think you know C? (2016)

#179

Having written a conforming C compiler, at one point I knew everything there was to know about C (I forget details now and then, or confusing them with C++ and D). But knowing every engineering detail is not the same thing as knowing how to program in C effectively. It's like being the engineer who designs a Grand Prix car. It does not mean you can drive it faster around the track than anyone else. Not even close. Fo…

I couldn't agree more. After spending many years working with LLVM, which is at its heart a C compiler, and understanding why it has to do the sometimes-terrifying things it has to do to get C to run well, I've become very paranoid when writing C or C++. My C/C++ code is as boring as possible.

(In fact I try to avoid writing C or C++ whenever possible these days; undefined behavior in the language is too pernicious and unfixable without breaking compatibility. I think both languages are approaching obsolescence.)

Re: So you think you know C? (2016)

#180
post #175

Having written a conforming C compiler, at one point I knew everything there was to know about C (I forget details now and then, or confusing them with C++ and D). But knowing every engineering detail is not the same thing as knowing how to program in C effectively. It's like being the engineer who designs a Grand Prix car. It does not mean you can drive it faster around the track than anyone else. Not even close. Fo…

Strong agreement here. You can limit yourself by choice to certain areas of the language that you know inside out (you know the asm they produce, etc.) and use it to solve problems. Don't worry about every single corner case. As you said, you can easily forget those things, especially if it's not your day-to-day job. The same idea and principle can be found in "JavaScript - The Good Parts".

Having recently been doing some web development, I'd argue that JavaScript's design (even today, despite some modern additions) is so conducive to undebuggable spaghetti code (i.e. this ) that there really are no good parts.

Sometimes the technology is objectively the wrong choice i.e. compiling javascript to native code (Not a JIT).

Post reply on HN