Live data from Hacker News

The Problem with Friendly C

blog.regehr.org

1–10 of 174 posts

Re: The Problem with Friendly C

#2
I think the most important point of Friendly C is not to define the behaviour for what would otherwise be undefined, but to define a behaviour; from this point of view, it would be unnecessary to argue over the examples he mentions like memcpy() vs memmove() and integer shifting --- it only suffices that every implementation define the behaviour, and what that behaviour precisely is can differ between them. A lot differs already between platforms, and so all this basically means is to document those differences. This agrees with the spirit of the language as a "high level assembler", removes all the undefinedness, and would be entirely unsurprising to most programmers.

The situation gets worse when we start talking about a friendly semantics for races and OOB array accesses.

I don't have anything to say about races, but OOB array accesses should simply do what you'd expect the hardware to do: attempt to access memory at the location the array indexing equation gives. It may segfault, or it may access some other contents in memory. That's what any C programmer would probably expect.

Re: The Problem with Friendly C

#3
If ((uint32_t)xBut why can't it just produce something different on each system?

Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course.

I don't know what to say.

Mandatory reading: http://robertoconcerto.blogspot.co.uk/2010/10/strict-aliasin... ("Everyone is fired"); https://groups.google.com/forum/#!msg/boring-crypto/48qa1kWi... ("these people simply don't understand what most C programmers want"); http://blog.metaobject.com/2014/04/cc-osmartass.html ("please don't do this, you're not producing value")

Re: The Problem with Friendly C

#4
It's easier to expand than contract. When the same decision is faced multiple times, it will be made multiple ways, and it's very difficult to remove one of those options once it's in use. On the other hand, if you remove the decision by standardizing on one of the options, you can always allow the other option later.

Working in Perl, I run into this a lot. When 'there is more than one way to do it' is a driving principle, it's easy to be inconsistent in usage and design. There's a tradeoff here -- it's easier to write code, because you can pretty much write your solution however it pops into your head. However, it's harder to read and maintain, because you have to recognize many many different patterns of usage. When code has been around for awhile, it starts to get an eclectic mix of patterns blended together, which can be frustrating to run into when you're trying to fix that code.

How do other people deal with this? Part of it is language choice, I'm sure. Large companies tend to use languages with less stylistic freedom, which helps teams write code more consistently. But within a given language, how do you balance freedom and consistency, so that people can understand each others' code effectively without being overly burdened by restrictions about how they can write code?

Re: The Problem with Friendly C

#5
How exactly would performance degrade by defining a virtual machine for C programs to run in where assurances are given that all of the standard behavior is fully defined -this operation either fails, or gives THIS result-? It sounds like it could be massively useful, at least for non-realtime applications.

Re: The Problem with Friendly C

#6
post #3

If ((uint32_t)x But why can't it just produce something different on each system? Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course. I don't know what to say. Mandatory reading: http://robertoconcert…

The, to me, obvious thing to do with code with undefined behaviour is to emit an error and refuse to compile it. Programmers should never rely on undefined behaviour.

Then again, I think languages shouldn't have undefined behaviour and that programmers who use languages with undefined behaviour deserve what they get.

Re: The Problem with Friendly C

#7
post #3

If ((uint32_t)x But why can't it just produce something different on each system? Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course. I don't know what to say. Mandatory reading: http://robertoconcert…

If the standard writers had wanted to, they could have specified that a shift by an amount as wide or wider than the type had an "implementation-defined result", which is used elsewhere (for example, right-shifting a negative value gives an implementation-defined result).

Re: The Problem with Friendly C

#8
post #6
post #3

If ((uint32_t)x But why can't it just produce something different on each system? Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course. I don't know what to say. Mandatory reading: http://robertoconcert…

The, to me, obvious thing to do with code with undefined behaviour is to emit an error and refuse to compile it. Programmers should never rely on undefined behaviour. Then again, I think languages shouldn't have undefined behaviour and that programmers who use languages with undefined behaviour deserve what they get.

In the most interesting cases, it can't reasonably be detected at compile-time anyway.

See also here:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-...

Re: The Problem with Friendly C

#9
post #3

If ((uint32_t)x But why can't it just produce something different on each system? Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course. I don't know what to say. Mandatory reading: http://robertoconcert…

Probably because it would go in the same direction as multiple-dialects proposal. If we can have bcc-x86 that returns x ans bcc-arm that returns 0, then we'll likely end up with bcc-x86-fullshifting-nounaligned-nullcheckremoveok-otheroptions and 10 dialects that switch some of those behaviours. If you're designing a well-defined language, then why make it well-defined-per-architecture?

Re: The Problem with Friendly C

#10
post #6
post #3

If ((uint32_t)x But why can't it just produce something different on each system? Allow me to call it as I see it: the modern interpretation of undefined behaviour is bullshit. What compilers do today should be the recourse of absolute last resort, and the sort of thing that makes its authors feel bad. But it seems to be treated as a matter of course. I don't know what to say. Mandatory reading: http://robertoconcert…

The, to me, obvious thing to do with code with undefined behaviour is to emit an error and refuse to compile it. Programmers should never rely on undefined behaviour. Then again, I think languages shouldn't have undefined behaviour and that programmers who use languages with undefined behaviour deserve what they get.

It's usually only at runtime rather than compile time that such situations arise.

At runtime we have the clang and gcc undefined behaviour sanitizers, but they aren't free in terms of performance.

Post reply on HN