Live data from Hacker News

Clang vs. Clang

blog.cr.yp.to

371–380 of 405 posts

Re: Clang vs. Clang

#371
post #253
post #114

Earlier quoted context omitted.

I am referring to undefined behavior. For example, consider the case integer overflow when adding two signed numbers. C considers this undefined behavior, making the program's behavior is undefined. All bets are off, even if the program never makes use of the resulting value. C compilers are allowed to assume the overflow can never happen, which in some cases allows them to infer that numbers must fit within certain…

Signed integer overflow being undefined has these two consequences for me: 1. It makes my code slightly faster. 2. It makes my code slightly smaller. 3. It makes my code easier to check for correctness, and thus makes it easier to write correct code. Win, win, win. Signed integer overflow would be a bug in my code. As I do not write my own implementations to correctly handle the case of signed integer overflow, the c…

Agreed. If anything, I'd like to have an unsigned type with undefined overflow so that I can get these benefits while also guaranteeing that the numbers are never negative where that doesn't make any sense.

Re: Clang vs. Clang

#372
post #268

Earlier quoted context omitted.

It is not a problem that different CPUs have different execution time, the problem is if the same CPU, running the same instruction has a timing difference depending on the data it operates on. In this regard CPUs have actually gotten better, specifically because it is a feature that AMD and Intel has pursued.

That includes branch predictions among other CPU optimizations.

If you have data-dependent branches then you have already lost. If you don't then I fail to see what data the branch predictor could possibly leak.

Re: Clang vs. Clang

#373

Earlier quoted context omitted.

> just speaking past each other here no I'm not if your program has UB it's broken and it doesn't matter if it currently happen to work correct under a specific compiler version, it's also fully your fault sure there is shared responsibility through the stack, but _one of the most important aspects when you have something like a supply chain is to know who supplies what under which guarantees taking which responsibil…

> your program has UB it's broken and it doesn't matter if it currently happen to work correct under a specific compiler version, it's also fully your fault Except that compiler writers essentially decide what's UB. Which is a conflict of interest. And they add UB, making previously non-UB code fall under UB. Would you call such code buggy?

Suppliers generally decide what guarantees they are able and willing to give, yes.

Re: Clang vs. Clang

#374

Earlier quoted context omitted.

There's a world of difference between code that's dead because of a static define, and code that's dead because of an inference the compiler made. A dead code report would be a useful thing, though, especially if it could give the reason for removal. (Something like the list of removed registers in the Quartus analysis report when building for FPGAs.)

#define DEBUG i The example is silly, but you should get the point. DEBUG can be anything.

Fair point, however your example is a runtime check, so shouldn't result in dead code.

(And if DEBUG is a static define then it still won't result in dead code since the preprocessor will remove it, and the compiler will never actually see it.)

EDIT: and now I realise I misread the first example all along - I read "#if (DEBUG)" rather than "if (DEBUG)".

Re: Clang vs. Clang

#375

Earlier quoted context omitted.

There's a world of difference between code that's dead because of a static define, and code that's dead because of an inference the compiler made. A dead code report would be a useful thing, though, especially if it could give the reason for removal. (Something like the list of removed registers in the Quartus analysis report when building for FPGAs.)

> There's a world of difference between code that's dead because of a static define, and code that's dead because of an inference the compiler made. Not really, that’s the problem. After many passes of transforming the code through optimization it is hard for the compiler to tell why a given piece of code is dead. Compiler writers aren’t just malicious as a lot of people seem to think when discussions like this come…

Yeah, I know the compiler writers aren't being deliberately malicious. But I can understand why people perceive the end result - the compiler itself - as having become "lawful evil" - an adversary rather than an ally.

Re: Clang vs. Clang

#376

Earlier quoted context omitted.

It specifically says that the use of C as a "portable assembler" is a use that the standards committee does not want to preclude. Not sure how much clearer this can be.

That statement means the comittee does not want to stop it from being developed. The question is, has it? They mean a specific implementation could work as portable assembler, mirroring djb's request for an 'unsurprising' C compiler. Another interpretation would be in the context of CompCert, which has been developed to achieve semantic preservation between assembly and its source. Interestingly this of course hints…

No.

C already existed prior to the ANSI standardization process, so there was nothing "to be developed", though a few changes were made to the language, in particular function prototypes.

C was being used in this fashion, and the ANSI standards committee made it clear that it wanted the standard to maintain that use-case.

Re: Clang vs. Clang

#377

Earlier quoted context omitted.

But having a straightforward/predictable mapping to the underlying machine and its semantics is included in the C model of computation. And that is actually not just compatible with the C "model of computation" being otherwise quite incomplete, these two properties are really just two sides of the same coin. The whole idea of an "abstract C machine" that unambiguously and completely specifies behavior is a fiction.

> But having a straightforward/predictable mapping to the underlying machine and its semantics is included in the C model of computation. While you can often guess what the assembly will be from looking at C code given that you're familiar with the compiler, exactly how C is to be translated into assembly isn't well-specified. For example, you can't expect that all uses of the multiplication operator "*" results in a…

> exactly how C is to be translated into assembly isn't well-specified.

Exactly! It's not well-specified so the implementation is not prevented from doing a straightforward mapping to the machine by some part of the spec that doesn't map well to the actual machine.

Re: Clang vs. Clang

#378
post #213

Earlier quoted context omitted.

> it's the C standard that is under specified to the author's liking Isn't this unreasonable? Here we are, 52, years down the road with C et al. and suddenly it's expected that compiler developers must consider any change in the light of timing attacks? At what point do such new expectations grind compiler development to a halt? What standard would a compiler developer refer to to stay between the lines? My instincts…

> short of regressing to in-order, non-speculative cores I guess you are referring to a GPU cores here. It is a joke but can hint that in-order non-speculative cores are powerful computers nonetheless.

You make a fine point. If you follow this regression to its limit you're going to end up doing your cryptography on a MCU core with a separate, controlled tool chain. TPM hardware has been a thing for a while as well. Also, HSMs.

This seems a lot more sane than trying to retrofit these concerns onto the entire stack of general purpose hardware and software.

Re: Clang vs. Clang

#379

Earlier quoted context omitted.

The compiler should emit the code to add one to a, and then code to check if the result is greater than a. This is completely evident, and is what all C and C++ compilers did for the first few decades of their existence. Maybe a particularly smart compiler could issue a `jo` instead of a `cmp ax, bx; jz `. The for loop example is silly. There is no reason whatsoever to add an overflow check in a for loop. The code of…

If you want the compiler to output exactly the code as written (or as close as possible to it for the target architecture), then most compilers support that. It's called turning off optimizations. You can do that if that's what you want. Optimizing compilers on the other hand are all about outputting something that is equivalent to your code UNDER THE RULES OF THE LANGUAGE while hopefully being faster. This condition…

> Optimizing compilers on the other hand are all about outputting something that is equivalent to your code UNDER THE RULES OF THE LANGUAGE while hopefully being faster.

The problem here is how far you stretch this "equivalent under the rules of the language" concept. I think many agree that C and C++ compilers have chosen to play language lawyer games to little performance in real world code, but introducing very real bugs.

As it stands today, C and C++ are the only mainstream languages that have non-timing-related bugs in optimized builds that aren't there in debug builds - putting a massive burden on programmers to find and fix these bugs. The performance gain from this is extremely debatable. But what is clear is that you can create very performant code without relying on this type of UB logic.

Re: Clang vs. Clang

#380
post #142
post #97

Earlier quoted context omitted.

> A big chunk of the essay is about a side point — how good the gains of optimization might be, which, even with data, would be a use-case dependent decision. I think this was useful context, and it was eye-opening to me.

If you were not aware of this then you might reflect on the part of my comment that he doesn’t bring up: how good/bad are use-case dependent. Every program optimizes for a use case, sometimes pessimizing for others (e.g. an n^2 algo that’s worthwhile because it is believed to only be called on tiny vectors). IMHO he was overgenerous on the optimization improvement of compilers. Often an optimization will make a diffe…

certainly
Post reply on HN