Earlier quoted context omitted.
Undefined behaviour has meant undefined behaviour. That doesn't mean nasal demons. That means this: Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the i…
the Standard imposes no requirements on undefined behaviour. The list you quoted is informative, to give us a basic idea what to possibly expect, not a list of things we may rely upon. Rejecting translation outright aside, undefined behaviour is the strongest language the standard uses for illegal constructs. I do not see it as undefined in the sense of lacking a common definition (eg is 0 a natural number, or not) b…
The Problem with Friendly C
31–40 of 174 posts
Re: The Problem with Friendly C
#32How 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
#33If ((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.
a->thing = 42;
if (a == NULL) {
return;
}
Obviously that code is wrong; I should check for NULL before using a. But because I dereferenced a, the compiler can assume a must not be NULL, and just removes the null check as dead code. This scenario has caused problems in the kernel, and made bad bugs even worse.Re: The Problem with Friendly C
#34Earlier quoted context omitted.
Apparently a (uint32_t) shifted by 32 is license to become completely insane. int main(int argc, char **argv) { uint32_t x = (uint32_t)0x12345678
I am almost LOLing at the segmentation fault. Where the fuck does a segmentation fault come from? It's shifting a value . Utterly mystifying.
Re: The Problem with Friendly C
#35I 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 dif…
You have to look deeper for the OOB array access question. For example, imagine I have code like this: if (a > 1) b++; array[b] = 0; c = a + 10; Under your suggested semantics, can the compiler use the value loaded from `a` at the point of the if() statement to calculate `a + 10`? Or does it have to emit a reload of `a` after the array access, in case `array[b]` was an OOB access that overwrote `a`?
Re: The Problem with Friendly C
#36Earlier quoted context omitted.
the Standard imposes no requirements on undefined behaviour. The list you quoted is informative, to give us a basic idea what to possibly expect, not a list of things we may rely upon. Rejecting translation outright aside, undefined behaviour is the strongest language the standard uses for illegal constructs. I do not see it as undefined in the sense of lacking a common definition (eg is 0 a natural number, or not) b…
Well I submit that as a simple question of quality of implementation, implementers should try their hardest to go for the something that behaves "in a documented manner characteristic of the platform"! But instead, they seem to pick something else. And I claim that this is not helpful to their users, who would be far better served by the characteristic-of-the-platform option.
Like it or not, the standard leaves the doorway open for the latter group to come up with increasingly aggressive optimization, only limited by their ingenuity.
Re: The Problem with Friendly C
#37Earlier quoted context omitted.
I think the problem is that some of these optimizations aren't just compiler makers being greedy, they're actually a huge benefit. IMO what's missing is the ability to mark areas "unsafe" -- IE, tell the compiler "it's ok to take advantage of certain optimizations here" while marking other areas "please don't goof with this" (ie, security critical code). You can kind of do this with pragmas, but not really. Here's a…
For example, knowing that INT_MAX+1 is undefined allows optimizing "X+1 > X" to "true". If a programmer writes "X+1 > X", chances are this is an overflow check. Doing this is perfectly defined by the standard if X is an unsigned integer, but not if it's signed. That's what doesn't make sense, since they could've made the unsigned case undefined as well. which allows a broad range of loop optimizations to kick in What…
Well, if you could remove one instruction per loop on most computers (especially conditionals that could cause a branch mis-prediction), the effect of that in terms of performance is pretty staggering. Instead of thinking of it as an optimization, think of it as a check that doesn't need to be inserted into the code. If you can tell the compiler "I promise I won't overflow this variable", that's a lot less error checking it needs to insert on every iteration.
> I don't believe C should be a language where the compiler does all sorts of high-level optimisation; it should be a straightforward "do what I say" type of language where you get almost exactly what you write
Well, you could just compile with -O0 then. I don't necessarily agree with C on this, but it's pretty clear the community has made the decision to prioritize speed over safety. Nothing wrong with that, but if safety is your priority you should probably look at things other than C. Even if you were to define undefined behavior, it's a spectacularly dangerous language.
Re: The Problem with Friendly C
#38Re: The Problem with Friendly C
#39I 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 dif…
You have to look deeper for the OOB array access question. For example, imagine I have code like this: if (a > 1) b++; array[b] = 0; c = a + 10; Under your suggested semantics, can the compiler use the value loaded from `a` at the point of the if() statement to calculate `a + 10`? Or does it have to emit a reload of `a` after the array access, in case `array[b]` was an OOB access that overwrote `a`?
Re: The Problem with Friendly C
#40There are going to be a lot of trade offs in any friendly C spec. Appreciation for both sides of a trade off is valuable in making good decisions.