Live data from Hacker News

The Problem with Friendly C

blog.regehr.org

111–120 of 174 posts

Re: The Problem with Friendly C

#111
post #28

Earlier quoted context omitted.

Maybe it's a hardware trap and not a regular null reference segmentation fault?

Well, shl doesn't trap on x86 for out of range values; it just masks the second operand by 0x1f [1]. But it could be some other kind of trap. Complete guess in the dark: tcc misencoded an instruction causing an illegal instruction trap, maybe in some sort of misguided attempt to optimize the shift to a lea. [1]: http://x86.renejeschke.de/html/file_module_x86_id_285.html

Wouldn't that normally produce SIGILL, not SIGSEGV?

Re: The Problem with Friendly C

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

It's a problem because that will lead to bugs. You write code on x86, it works for years and then you let it run on ARM and it will misbehave. If it weren't a problem, then the compiler doing whatever it wants also wouldn't be a problem.

IMO the best thing would be if the compiler would insert code to print to screen a warning and exit the program, if it comes across undefined behaviour. (This is different from sanitizers, that check for all places whether undefined behaviour will occur).

Re: The Problem with Friendly C

#113
post #110
post #106

Earlier quoted context omitted.

Hardware doesn't work like this. You might want to read Hennessy and Patterson, and the original RISC I paper. http://www.amazon.com/Computer-Architecture-Fifth-Edition-Qu... http://www.cecs.pdx.edu/~alaa/ece587/papers/patterson_isca_1...

RISC created a huge local minimum by speeding up C code to the exclusion of other languages. I predict that eventually future processors will hide more features from the higher software levels (such as number of registers, instruction types and formats) in order to improve efficiency at the machine level. I think we are seeing this trend with GPUs already. Current CPUs don't do this because they have to maintain bina…

Current processors already do that. You don't see the true number of registers or the true instruction set/format of any modern Intel processor. x86 instructions are translated into micro-ops, so x86 is really just a compatibility layer.

I do agree that current processors optimize for C/C++ (although of course there are niche systems like Azul which optimize for other languages). It would be nice to have processor extensions that allow us get better GC performance, or better handling of immutable values. There's a chicken-and-egg problem getting there.

Re: The Problem with Friendly C

#114
post #110
post #106

Earlier quoted context omitted.

Hardware doesn't work like this. You might want to read Hennessy and Patterson, and the original RISC I paper. http://www.amazon.com/Computer-Architecture-Fifth-Edition-Qu... http://www.cecs.pdx.edu/~alaa/ece587/papers/patterson_isca_1...

RISC created a huge local minimum by speeding up C code to the exclusion of other languages. I predict that eventually future processors will hide more features from the higher software levels (such as number of registers, instruction types and formats) in order to improve efficiency at the machine level. I think we are seeing this trend with GPUs already. Current CPUs don't do this because they have to maintain bina…

> RISC created a huge local minimum by speeding up C code to the exclusion of other languages

Would you mind expanding this.

Re: The Problem with Friendly C

#115
post #79

Earlier quoted context omitted.

The problem here is, as you point out, the conversion of double to unsigned byte. More specifically, the problem is that processing this operation is not producing error; it instead propagates the problem and produces invalid code. That's a situation where nobody wins. I think we'd be better off if many undefined behaviours were instead implementation defined. If, instead, LLVM had converted the double to some intege…

> On strict aliasing, I'm against it without explicit opt-in over a delimited subset of source code. I understand that using & is going to harm the performance of my code; I think that's an acceptable tradeoff for more predictable behaviour. I believe that you and others think that's an acceptable tradeoff. At the end of the day, though, most people want C compilers to produce the fastest code possible. Compiler auth…

Wouldn't the compiler be capable of noticing that if the array[0] is assigned to zero while

- array pointer points to pointer itself, then the pointer is set to NULL pointer (assuming architecture where float 0 and NULL are represented in memory by zero), and derefencing null pointer is an undefined behaviour

- array points to misaligned itself (possible on x86), then there is a write outside of variable bounds, and undefined behavior

- array points to part of zero_out or memset function code, however the function is constant, and cannot be changed, and this causes undefined behavior

In each of these cases, there is an undefined behavior not depending on strict aliasing.

Re: The Problem with Friendly C

#116

Being an ignorant fool with an uninformed opinion, I would like to see a C compiler that is evaluated and critiqued not only based on the warnings and errors it generates but, more importantly, on the assembly it generates. Namely, how compact and readable is the generated asm? When we read the asm, can we easily follow what the compiler has done and _why_? As an ignorant fool, in my mind C is still a shorthand for w…

"_compact_ and readable"

For me, the former compliments the later. The less code I have to read, the better.

Re: The Problem with Friendly C

#117
post #54

Earlier quoted context omitted.

But the compiler could just as well emit a warning "useless NULL comparison" instead of blithely assuming that the programmer intentionally wrote a book expression. That wouldn't handle every case of UB, but would handle many.

A warning on removed dead code isn't helpful because dead come is legitimately removed all the time. No one would ever heed it.

If you ignored dead code produced by macros and limited the check to function-scope, I think you'd mostly eliminate false positives.

Re: The Problem with Friendly C

#118

Earlier quoted context omitted.

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…

> What sort of optimisations exactly, and just how significant are they? 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…

> but if safety is your priority you should probably look at things other than C

And those things are?

C is the low level language we have. Now compiler writers decided it'll work like a high level language, except for all the actual benefits.

We'll probably get usable C compilers that work (in fact, this already started), and some stuff only good for old code.

Re: The Problem with Friendly C

#119

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

As the article points out, weird looking comparisons like `x+1>x` tend to pop up when macros get expanded or functions get inlined.

Re: The Problem with Friendly C

#120
post #60

Earlier quoted context omitted.

> But why can't it just produce something different on each system? It could. That is indeed how Rust, for example, defines it. But in C "unspecified values" have a way of turning into undefined behavior really quickly. Here's an actual bug we have in Rust [1]: let index = 1.04E+17 as u8; let array = vec![1, 2, 3, 4, 5]; println!("{}", array[index as usize]); // segfault Why does that segfault instead of emitting a s…

For anyone wondering: double -> uintx_t is indeed undefined in C and C++ for values outside of (0, UINTx_MAX), which is kind of a gotcha since, double -> long -> uint8_t is fine (assuming all integer parts of double fit in a long).

Which they don't? Right?
Post reply on HN