Live data from Hacker News

Deconstructing "K&R C"

c.learncodethehardway.org

101–110 of 136 posts

Re: Deconstructing "K&R C"

#101
post #79
post #53

Earlier quoted context omitted.

It's way worse than an extra byte, or the offset of 1 byte for pointers; it also means you need a whole copy of every substring with its own length delimiter, and can't tokenize in place. C code gets into just as much trouble with length-delimited data structures as it does with ASCIIZ; ASCIIZ is a red herring. People have declared over and over again that it's the single worst decision in C and the cause of every bu…

I partially agree with you, but in a different way. I feel that the real problem is the OS doesn't give code access to its own internal accounting of allocated memory. It already knows the size of any heap chunk you make, so why can't we ask it? In most C code we're carrying around either a null terminator (which can get clobbered) or a whole integer for the size. Instead, there should be a way to ask the OS "how big…

Hmm. The question "what is the size of memory that x points to?" is cheap to figure out, because free needs to do it anyway. You couldn't use a macro to do it - it would need to access the internal data structures of the allocator - but it's easy to do. The other questions could be macros that called the first function.

What are the use cases for these functions? What bugs would they prevent?

Re: Deconstructing "K&R C"

#102
post #79

Earlier quoted context omitted.

I partially agree with you, but in a different way. I feel that the real problem is the OS doesn't give code access to its own internal accounting of allocated memory. It already knows the size of any heap chunk you make, so why can't we ask it? In most C code we're carrying around either a null terminator (which can get clobbered) or a whole integer for the size. Instead, there should be a way to ask the OS "how big…

Hmm. The question "what is the size of memory that x points to?" is cheap to figure out, because free needs to do it anyway. You couldn't use a macro to do it - it would need to access the internal data structures of the allocator - but it's easy to do. The other questions could be macros that called the first function. What are the use cases for these functions? What bugs would they prevent?

Worth pointing out again: the size of the chunk allocated for a particular data structure does not give you the precise bounds of the data structure; odds are, the chunk is slightly larger than the structure.

Re: Deconstructing "K&R C"

#103
post #61
post #8

I'm confused. What is the "defect" in K&R's "copy(char to[], char from[])" function? The author notes that "the second this function is called...without a trailing '\0' character, then you'll hit difficult to debug errors", but no function with that signature could possibly work in this case. The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Null-termination…

> but no function with that signature could possibly work in this case. This is the source of the bugs in C. People write functions that only work given all calls to them are never changed, which is absurd. Good modern C code involves trying to protect against bad usage and adding defensive checks. So yes, the built-in strcpy is crap which is why most competent C doesn't use it except in a few rare cases where it's r…

this from the man who won't describe xargs to newbies because he doesn't understand it.

blargh

Re: Deconstructing "K&R C"

#104
I'm sure I'll be downvoted, but C is not Java.

From what I can tell, the "it's time for C to go" comes from a generation raised on Java.

C still has its place.

Re: Deconstructing "K&R C"

#105
post #76

Kind-of a long-winded way to point out the (very well known) fact that passing non-terminated strings to functions that expect terminated strings is fraught with danger, isn't it?

Nope, and what I'm actually doing is fuzzing the input to this function, which is a common breaking technique. You see, programmers tend to go around only using functions exactly as they were intended. Hackers come along and then use them in unintended ways, which causes bugs. The way to prevent this is to think like a hacker and try to use your code in unintended ways and then try to prevent them.

You say 'hackers' like it's a bad thing. As a reminder, this is "Hacker News".

Re: Deconstructing "K&R C"

#106

Earlier quoted context omitted.

Hmm. The question "what is the size of memory that x points to?" is cheap to figure out, because free needs to do it anyway. You couldn't use a macro to do it - it would need to access the internal data structures of the allocator - but it's easy to do. The other questions could be macros that called the first function. What are the use cases for these functions? What bugs would they prevent?

Worth pointing out again: the size of the chunk allocated for a particular data structure does not give you the precise bounds of the data structure; odds are, the chunk is slightly larger than the structure.

I wrote a response explaining why, if you know x then you must know y, but then I realized you were talking about knowing y and learning x. Yes, I agree. I'm not sure which context (knowing the actual size of the memory chunk, which is easy, or knowing the used size of the memory chunk, which is not easy) Zed was talking about.

Re: Deconstructing "K&R C"

#107
post #74
post #13

Earlier quoted context omitted.

Agreed, the example used seems very strange. Every function makes functions about it's parameters and in C null terminated string are to be assumed unless otherwise noted. The std library strcpy would just behave in an identical way. Yeah, I'm all about checking your assumptions and defensive programming but k&r is hardly as fault because you throw garbage at a random function and it segfaults. I find the idea of tea…

You should go read about fuzzing. It's amazing what throwing "random garbage" at programs can break.

Passing random garbage to a random function is not the same as passing random input to a program.

Take for example one of the most common bugs in C (even more common than not null terminating strings I'll say) passing already freed memory, are you going to argue that a function has a bug because it'll randomly give root access to outsiders because someone took it out of context and passed a stray pointer to it.

Calling a function that expects to get a null terminated string buggy because you passed a pascal string and it crashes seems weird at least. I'll call it potentially dangerous when misused (like most of C code anyway), but not buggy, since it's behaved as designed.

C is an unsafe language and yes, you can validate a lot of things, but at the end of the day it's still a unsafe language, the solution in my opinion is to advocate the use of safer languages and only use C for when it's strictly necessary.

Re: Deconstructing "K&R C"

#108
post #96
post #83

Earlier quoted context omitted.

To be both pedantic and correct, there is no way to define a C function to restrict a string input so that it is correctly terminated. So no, it's at best documented that you shouldn't do that and definitely doesn't prevent you from doing this.

To be still more pedantic, there are two kinds of definition of an interface: definition-within-the-type-system and definition-within-the-documentation. The string library is specified in the ISO C standard (I use C99, but you can be all hip and C11 if you want), and passing an unterminated string to strcpy is a constraint violation. 7.1.1 A string is a contiguous sequence of characters terminated by and including th…

Right, the C language type system makes no attempt at describing that kind of constraint, yet it is still clearly defined within the language.

And it's not just the standard C library that defines it...this definition of string is also supported by the literal string data type.

Re: Deconstructing "K&R C"

#109

Earlier quoted context omitted.

Redis strings are actually length prefixed null terminated strings

The string data type in the db? Because Redis itself uses char-stars all over the place, with the libc string functions.

Hmm, reading the source it looks like he is using His sds string library, which has Len, size and a asciiz char* member. When last I checked he does pass the char* around (because it is null terminated) but he also sometimes will do pointer math to get back to the sds

Re: Deconstructing "K&R C"

#110
post #63

Earlier quoted context omitted.

"the majority of good C code just doesn't use C style strings..." Nice. In the 23 years I have worked on C language products, I've never worked on "good C code" by this definition. The cool thing about this guys book, I guess, is that by avoiding all the things about the language he doesn't like, any reader will be wholly unprepared for C in the Real World after this book.

Yes, they'll be pretty good at C unlike you because they'll read the whole book instead of just this one half-finished chapter.

"they'll be pretty good at C unlike you"

Thanks for the code review of my last 23 years of work on C projects. Nice ego that your book must be the only way to learn this.

I mostly disagree with your statement about "most good C code" not using stdlib strings/apis.

To be fair, from your comments here, it looks like you aren't really saying that -- you are saying we have to be careful when using them. This I know, and carefully guard against, and I do try to break my code regularly. But to assert that "most good C code" doesn't use them fails to meet with my experience.

That said, _all_ bad C code (ab)uses them, probably due to carelessness and/or misunderstanding of how things work in C.

Post reply on HN