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
The Problem with Friendly C
111–120 of 174 posts
Re: The Problem with Friendly C
#112If ((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…
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
#113Earlier 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…
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
#114Earlier 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…
Would you mind expanding this.
Re: The Problem with Friendly C
#115Earlier 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…
- 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
#116Being 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…
For me, the former compliments the later. The less code I have to read, the better.
Re: The Problem with Friendly C
#117Earlier 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.
Re: The Problem with Friendly C
#118Earlier 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…
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
#119Earlier 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…
Re: The Problem with Friendly C
#120Earlier 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).