Live data from Hacker News

Tell HN: C Experts Panel – Ask us anything about C

news.ycombinator.com

481–490 of 978 posts

Re: Tell HN: C Experts Panel – Ask us anything about C

#481
post #475
post #466

If an old timer who used to be good with C wanted to use C again, would they have to learn a whole bunch of weird new stuff or could they pretty much use it like they did back in the stone age (i.e., the 20th century)? Back in the '80s and '90s I was pretty good at C. I don't think there was anything about the language or the compilers than that I did not understand. I used C to write real time multitasking kernels f…

C17 doesn't look much different than C89. If you are used to K&R C there may be some adjustment but I would expect it to be manageable. What might perhaps be more challenging is adjusting to the changes in compilers. They tend to optimize code more aggressively and so writing code that closely follows the rules of the language (rather than making assumptions about the underlying hardware, even valid ones) is more imp…

Given the above, it is worth pointing out that the compilers are also much much better in verification and useful warnings/errors. Back in the (very old) days, there was a motivation to cut down PCC (Portable C Compiler) and give the birth to Lint as a separate application (because cutting the compilation time was a greater priority). The current trends are completely the opposite: compilers are getting increasingly more powerful built-in static analyzers and sanitizers by default.

I think the lack of powerful tools in 1990s-2000s contributed to the thought by some that C is 'diffcult' in terms of safety. However, things have moved on.

Re: Tell HN: C Experts Panel – Ask us anything about C

#482
Is there any reason to keep the undefined behavior for shifts of negative numbers, instead of making it implementation defined? Most compilers (for twos-complement architectures at least) are not using that latitude, and I would also guess that most programs that are written for twos-complement arithmetic likewise not expecting undefined behavior for non-overflowing left shifts of negative numbers. Thanks!

Re: Tell HN: C Experts Panel – Ask us anything about C

#484

Earlier quoted context omitted.

> C's charter is to standardize existing practice (as opposed to invent new features) Passing a pair of arguments (pointer and a length) is surely one of the more universal conventions among C programmers?

When they say "existing practice" they mean things already implemented in compilers -- not existing practice among developers.

This seems like a poor way to establish criteria for standardization. It essentially encourages non-standard practice and discourages portable code by saying that to improve the language standard we have to have mutually incompatible implementations.

It has been said that design patterns (not just in the GOF sense of the term) are language design smells, implying that when very common patterns emerge it is a de facto popular-uprising call for reform. That, to me, is a more ideal criterion for updating a language standard, but practiced conservatively to avoid too much movement too fast or too much language growth.

On the other hand, I think you might be close to what they meant by "existing practice". I'm just disappointed to find that seems like the probable case (though I think it might also include some convergent evolutionary library innovations by OS devs as well as language features by compiler devs).

Re: Tell HN: C Experts Panel – Ask us anything about C

#485

Earlier quoted context omitted.

Just going to inject that this impacts a bunch of random optimizations and benchmarks. Just to fabricate an example: for (int i = 0; i Reasonably common idea but the compiler is allowed to assume the loop terminates precisely because signed overflow is undefined. I’m not trying to argue that signed overflow is the right tool for the job here for expressing ideas like “this loop will terminate”, but making signed over…

the compiler is allowed to assume the loop terminates precisely because signed overflow is undefined. Just to be sure I understand the fine details of this -- what would the impact be if the compiler assumed (correctly) that the loop might not terminate? What optimization would that prevent?

> …what would the impact be if the compiler assumed (correctly) that the loop might not terminate?

Loaded question—the compiler is absolutely correct here. There are two viewpoints where the compiler is correct. First, from the C standard perspective, the compiler implements the standard correctly. Second, if we have a real human look at this code and interpret the programmer’s “intent”, it is most reasonable to assume that overflow does not happen (or is not intentional).

The only case which fails is where N = INT_MAX. No other case invokes undefined behavior.

Here is an example you can compile for yourself to see the different optimizations which occur:

    typedef int length;
    int sum_diff(int *arr, length n) {
        int sum = 0;
        for (length i = 0; i 
At -O2, GCC 9.2 (the compiler I happened to use for testing) will use pointer arithmetic, compiling it as something like the following:

    int sum_diff(int *arr, length n) {
        int sum = 0;
        int *ptr = arr;
        int *end = arr + n;
        while (ptr 
At -O3, GCC 9.2 will emit SSE instructions. You can see this yourself with Godbolt.

Now, try replacing "int" with "unsigned". Neither of these optimizations happen any more. You get neither autovectorization nor pointer arithmetic. You get the original loop, compiled in the most dumb way possible.

I wouldn’t read into the exact example here too closely. It is true that you can often figure out a way to get the optimizations back and still use unsigned types. However, it is a bit easier if you work with signed types in the first place.

Speaking as someone who does some numerics work in C, there is something of a “black art” to getting good numerics performance. One easy trick is to switch to Fortran. No joke! Fortran is actually really good at this stuff. If you are going to stick with C, you want to figure out how to communicate to the compiler some facts about your program that are obvious to you, but not obvious to the compiler. This requires a combination of understanding the compiler builtins (like __builtin_assume_aligned, or __builtin_unreachable), knowledge of aliasing (like use of the "restrict" keyword), and knowledge of undefined behavior.

If you need good performance out of some tight inner loop, the easiest way to get there is to communicate to the compiler the “obvious” facts about the state of your program and check to see if the compiler did the right thing. If the compiler did the right thing, then you’re done, and you don’t need to use vector intrinsics, rewrite your code in a less readable way, or switch to assembly.

(Sometimes the compiler can’t do the right thing, so go ahead and use intrinsics or write assembly. But the compiler is pretty good and you can get it to do the right thing most of the time.)

Re: Tell HN: C Experts Panel – Ask us anything about C

#486

Earlier quoted context omitted.

Just going to inject that this impacts a bunch of random optimizations and benchmarks. Just to fabricate an example: for (int i = 0; i Reasonably common idea but the compiler is allowed to assume the loop terminates precisely because signed overflow is undefined. I’m not trying to argue that signed overflow is the right tool for the job here for expressing ideas like “this loop will terminate”, but making signed over…

the compiler is allowed to assume the loop terminates precisely because signed overflow is undefined. Just to be sure I understand the fine details of this -- what would the impact be if the compiler assumed (correctly) that the loop might not terminate? What optimization would that prevent?

If the compiler knows that the loop will terminate in 'x' iterations, it can do things like hoist some arithmetic out of the loop. The simplest example would be if the code inside the loop contained a line like 'counter++'. Instead of executing 'x' ADD instructions, the binary can just do one 'counter += x' add at the end.

Re: Tell HN: C Experts Panel – Ask us anything about C

#487
post #388

When do you think we will get an update to C11 or more recent version of C to MISRA? Do you all have any influence on "Safety Critical C" standards?

The MISRA committee is a separate organization from the C standards committee, but there is overlap between the two groups and an official liaison process for the committees to collaborate. So there's a bit of bidirectional influence between the two groups.

I am not on the MISRA committee, but I believe they talk a bit about their public roadmap in this video: https://vimeo.com/190304951

Re: Tell HN: C Experts Panel – Ask us anything about C

#488
post #262

Earlier quoted context omitted.

Huh, it also needed an extra line break before the first line of code. I didn't realize that! I've fixed it now.

I didn't realize that either, but it's described in formatdoc as such. So if you changed that behavior, probably should change the docs too.

I didn't change the behavior - I just added a newline. Sorry that wasn't clear.

Re: Tell HN: C Experts Panel – Ask us anything about C

#489
post #457
post #327

Earlier quoted context omitted.

You do have to understand that compiler teams aren't saying something like "this triggers UB, quick just replace it with noop." It's just something that naturally happens when you need to reason about code. For example, consider a very simple statement. let array[10]; let i = some_function(); print(array[i]); The function might not even be known to the compiler at compilation time if it was from a DLL or something. B…

> But the compiler is like "hey! you used the result of this function as an index for this array! i must be in the range [0, 10)! I can use that information!" As a developer who has seen lots of developers (including himself) make really dumb mistakes, this seems like a very strange statement. Imagine if you hired a security guard to stand outside your house. One day, he sees you leave the house and forget to lock th…

> in a lot of cases, it will be harmless; and in the worst case it will crash with a segfault.

I am not sure if a segfault is always the worst case. It could be by some coincidence that array[i] contains some confidential information [maybe part of a private key? 32 bits of the user's password?] and you've now written it to a log file.

I know it's hard to imagine a mis-read of ~32 bits would have bad consequences of that sort, but it's not out of the question.

Re: Tell HN: C Experts Panel – Ask us anything about C

#490
post #468

What has been the rationale or hinderance for not adding locale-independent versions of various stdlib functions? Practically every second C codebase on earth has their own implementations of these at some point, and it remains a huge problem for e.g. writers of libraries, where you don't know how/where your library will be used.

First, there needs to be a proposal for adding a feature (I'm not aware of one having been submitted recently). Second, any non-trivial proposed feature needs to have some existing user experience behind it. For libraries that typically means implementations shipping with operating systems or compilers (but successful third party libraries might also be considered). Finally, it also needs to appeal to people on the c…

Sounds mostly like the issue is nobody has bothered to submit a proposal for it then? (There is so much in-the-wild experience and code dealing with this issue, I cannot imagine the second point being problematic.)

On the third point, I have trouble thinking of any technical objections to such proposal.

Post reply on HN