Live data from Hacker News

A critique of "How to C in 2016"

github.com

131–140 of 181 posts

Re: A critique of "How to C in 2016"

#131

Earlier quoted context omitted.

> I would argue that any code doing anything under the assumption that a char variable occupies 8 bits in memory and that the next char in an array is physically adjacent to it with no wasted space in between is just poorly-written and inherently not portable I don't think that's fair at all. It's well written and perfectly portable, under that assumption . If that assumption happens to hold for all the systems that…

> If that assumption happens to hold for all the systems that could is meant to run on, why shouldn't you make it? Because what's going to happen two years down the road when you need to get that code working on a different platform. (In the old days, they called that thinking "all the world's a VAX", which became "all the world's linux" in the not-quite-as-old days)

> Because what's going to happen two years down the road when you need to get that code working on a different platform.

And what happens when the different platform handles overflow differently? Or has non-IEEE floats? Or breaks whatever assumption the C standard already makes?

Here's the thing: C is already built on assumptions, which might or might not hold for a specific platform.

Choosing which assumptions we hold true is a pragmatic choice that must be done. C does it, and does it consciously - but it doesn't mean that it nails every choice.

Re: A critique of "How to C in 2016"

#132
post #5

> Zeroing memory often means that buggy code will have consistent behavior; by definition it will not have correct behavior. And consistently incorrect behavior can be more difficult to track down. I agree that using calloc should not be an excuse for writing sloppy initialization code. But in my experience, inconsistently incorrect behaviour (e.g. heisenbugs that tend to appear and disappear depending on the content…

All of that useless zeroing is very painful from a performance perspective. It just isn't a reasonable option in performance-relevant code like kernels and core infrastructure. The Moore's Law argument doesn't apply because memory bus latencies and case pressure are lasting problems.

Re: A critique of "How to C in 2016"

#133
post #38

Earlier quoted context omitted.

>You'd break de facto compatibility with almost all C code for no reason. The authors of that code should have written portable code if they didn't want it to break.

Texhnically, they did. The go to compiler for years was GCC, with all the GNU extensions turned on. The problem is that those extensions were classically on by default, so it was very easy to just use them without thinking too much about it.

On GNU/Linux, yes.

Outside world, there are tons of C compilers to chose from.

Re: A critique of "How to C in 2016"

#134
post #71

Isn't another problem of "ptrdiff_t diff = (uintptr_t)ptrOld - (uintptr_t)ptrNew;" that you're assigning an unsigned value to a signed variable? If ptrNew is larger than ptrOld this can give a very large value via wrapping around, so large that it will probably be bigger than the max value of ptrdiff_t, making the assignment a form of signed overflow.

The assignment is a conversion from unsigned to signed, if the value cannot be represented by the signed type, the result is implementation defined or an implementation defined signal is triggered.

Right. Implementation defined, not undefined. Still not great for portable code, which is what the article is all about.

Re: A critique of "How to C in 2016"

#135

The discussion usually boils down to a. We need a better C b. We need better programmers. Personally I believe C tries to hard to be high level instead of what it really is. Newer revisions should try to make it lower level. For example I never could understand why we need enums. Enums are very useful for Java or Golang which are high-level. C never needs enums. Why should I ever put const in the argument of a functi…

The thing is, such higher level systems programming languages were already a thing in the 60's.

C designers just wanted to hack something for their toy OS and here we are.

Re: A critique of "How to C in 2016"

#136

> The first rule of C is don't write C if you can avoid it. My C skills are non-existent, but it occurs to me while reading the response that when two people who have so carefully considered the subject can arrive at such different places... then yes, you probably shouldn't write C if you can avoid it.

C is the only language that will run on certain strange systems, and that is the only reason that most of these quibbles even matter. It's more of an argument of "What is the most portable way to write C?" C is a very small and elegant language that never lies to you. There aren't any useless functions that are specific to one use case, and things that you don't really, really need are simply left out of the language…

> C is a very small and elegant language that never lies to you.

I would call undefined behavior and compiler optimizations lies.

Re: A critique of "How to C in 2016"

#137

Earlier quoted context omitted.

You can use char, and for the most part you won't notice any difference, until you start looking at the memory display in your IDE and have a short-lived WTF moment. A c-string looks strange in the memory view because there's a NULL octet between each character but that's an implementation detail that you don't really notice 99% of the time, because everything on the processor is designed to use 16-bit words. If you…

> I would argue that any code doing anything under the assumption that a char variable occupies 8 bits in memory and that the next char in an array is physically adjacent to it with no wasted space in between is just poorly-written and inherently not portable I don't think that's fair at all. It's well written and perfectly portable, under that assumption . If that assumption happens to hold for all the systems that…

ehmmmm standard C has floats and doubles. so they are valid C

>Why assuming that unsigned integers overflow to 0 is fair

because the standard says so

In your other posts I noticed some more misunderstanding of the C standard, so I suggest not to talk about things you are not aware about.

Re: A critique of "How to C in 2016"

#138
post #57

> int in particular is going to be the most "natural" integer type for the current platform. If you want signed integers that are reasonably fast and are at least 16 bits, there's nothing wrong with using int The slight performance gain on a few systems that you get from using int rather than int16_t is very rarely worth the hugely increased risk of introducing platform-specific undefined behaviour, IMO. > float and…

>The slight performance gain on a few systems that you get from using int rather than int16_t

int16_t is also unportable as he mentions later

>the hugely increased risk of introducing platform-specific undefined behaviour

What risk? Please explain how int introduces undefined behaviour.

>how much performance

It's not about performance. intN_t is NOT guaranteed to exist.

>But you just said in the previous section that it only makes sense to perform pointer arithmetic within a single object anyway.

Yes and that's right.

Re: A critique of "How to C in 2016"

#139
post #9

I disagree with many of the arguments. Many of them are ignoring the reality of today. One example: > If you want bytes, use unsigned char. If you want octets, use uint8_t Bytes and octets are the same today. I never came across a system where this wasn't true. I was never told about a system where this wasn't true. I wasn't even told that there once were systems where this wasn't true until fairly recently.

The XAP processor architecture use in CSR Bluetooth Chips (design orginally from Cambridge Consultants) is one such processor.

On it: A 'byte' is 16 bits. A word is 16 bits (so sizeof(int) == 1) A function ptr is 24 bits (so sizeof(Fx) == 2)

CSR have sold well over a billions chips. There is a strong argument that this is the 3rd most popular architecture family after ARM and X86/64.

Things that x86 programmers do that won't work because they make assumptions the C standard doesn't specify: Cast a uint16_t* to uint8_t* to extract the upper and lower octets of the uint16 (a uint8_t array is actually in memory a uint16_t array using only the lower 8 bits) Store a function pointer in a void* (throws away upper 8 bits of the 24 bit func pointer).

Re: A critique of "How to C in 2016"

#140
post #5

> Zeroing memory often means that buggy code will have consistent behavior; by definition it will not have correct behavior. And consistently incorrect behavior can be more difficult to track down. I agree that using calloc should not be an excuse for writing sloppy initialization code. But in my experience, inconsistently incorrect behaviour (e.g. heisenbugs that tend to appear and disappear depending on the content…

The tools for rooting out these problems have gotten a lot better, thankfully. I'm very fond of the address sanitizer. Using calloc() everywhere can prevent the address sanitizer from finding problems.

You could try to split the difference by using a wrapper around malloc that zeroes in production and doesn't under testing.

Of course, running significantly different code in production and test has its own issues.

Post reply on HN