Live data from Hacker News

Learn C The Hard Way

c.learncodethehardway.org

51–60 of 69 posts

Re: Learn C The Hard Way

#51
post #28

Earlier quoted context omitted.

Wrong, I make a clear example of the copy() function being broken, give a demonstration of fuzzing it to break it, and show how to do it yourself. And, if you think the copy() function is valid, then you also think strcpy() function is valid, and therefore you don't know what you're talking about. Everyone who is aware of secure C coding knows strcpy() is buggy and the cause of most buffer overflows.

Dude, stop saying it's broken. For higher level languages where we have intelligent string objects, yeah, bounds checking is assumed--but this is something originating in assembly-level stuff. If you call it with broken memory, of course it won't work correctly. You're doing a good job spreading knowledge--don't spread misinformation. Everyone who is aware of secure C coding knows strcpy() is buggy and the cause of m…

Zed's Twitter killfile must be a mile long if this got me into it: https://gist.github.com/9efed904a1ea0902c7c7/213de692d29fdde...

He's right though. This really is a silly argument. Your life will almost certainly be better if you forget strcpy exists.

Really, C strings are broken in general. Computing their length is O(n) when it could be O(1), and a missing null terminator results in undefined behavior (a crash if you're lucky). Worse, copying an oversized string into an undersized buffer results in a buffer overflow, which gets you a nice mention here: http://www.kb.cert.org/vuls.

strcpy is about as safe as a hand grenade: you'll be fine if you know what you're doing, but God help you if you don't!

Realistically, if you're reading "Learn C The Hard Way," you don't know what you're doing yet. Don't use strcpy.

For that matter, you're human. You screw up sometimes. We all do. Don't use strcpy without a damn good reason.

Is there ever a legitimate reason to use strcpy over strncpy?

Re: Learn C The Hard Way

#52
post #40

OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? I asked this question of a younger programmer the other day, because it seemed to me, that to HIM, learning C was a rite of passage, and that he was less of a man for not knowing it. I find macho philosophies in software development both amu…

>> OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++?

Why does a medical doctor have to learn a little bit of Latin? After all, you should be able to find all the books and material you need in your native language or at least English.

C is to computing what Latin is to medicine. There's just so much history and important code written in C, that it's an important skill to master. Or at least know a little about.

These days you can spend your entire career in the comfort of a high level language working on a virtual machine and make a fortune. However, if you don't know C (and the fundamentals of how computers work) you'll be standing on a foundation that you cannot understand like a living in a cargo cult.

If you're passionate about computing and software engineering, you'll have a natural interest in how things work under the hood. Learning C is almost mandatory if you want to see how deep the rabbit hole is. Knowing it will certainly help when exploring the intricacies of processors and operating systems.

Learning C++, on the other hand, I think is optional. I'm pretty seasoned with C++ but these days I prefer plain old C for low-level tasks. In theory, it may be possible to learn C++ without knowing C, but in practice it's not. If you try to write anything with C++, it will be inevitable that you'll have to interface with C code. std::string and std::map are very nice but there's a ton of tasks that require using a C API (maybe through a wrapper layer).

Embedded and other low-level tasks are often written in C because in order to run C++, you need runtime support for exceptions, static & global constructors, etc. Porting the C++ standard library is even more painful. C++ without exceptions has very little advantage over plain C.

Re: Learn C The Hard Way

#53
post #52
post #40

OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? I asked this question of a younger programmer the other day, because it seemed to me, that to HIM, learning C was a rite of passage, and that he was less of a man for not knowing it. I find macho philosophies in software development both amu…

>> OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? Why does a medical doctor have to learn a little bit of Latin? After all, you should be able to find all the books and material you need in your native language or at least English. C is to computing what Latin is to medicine. There's jus…

> If you're passionate about computing and software engineering, you'll have a natural interest in how things work under the hood.

When I was 12, I learned 6502 assembly language. The computer I had did not have a C compiler, only BASIC or assembler (you could also enter hex into memory locations, which was hardcore). Learning assembly is actually a LOT easier than people make out. Assembly is basically mnemonics for the underlying machine code, plus named locations. Assembly has everything a language needs for Turing completeness. Assign, Add, Subtract, Compare, Branch. And THAT is how the computer works 'under the hood'. C is one level of abstraction above that, and while it's true that a LOT of software has been historically written in C, before C came along, most software was written in assembler or BASIC (which is older than C, for the historians).

> Learning C is almost mandatory if you want to see how deep the rabbit hole is.

Not really. I know what is going on 'down there', regardless of which language was used to compile the machine code. What is REALLY useful is to have really succinct, powerful, high-level abstractions to build software quickly and with as little code as possible.

> Knowing it will certainly help when exploring the intricacies of processors and operating systems.

If that's what you want to do, then fine. I'm too much of a utilitarian for that kind of exploration. I want to build stuff.

I think if you want to understand what's going on 'down there' in the 'rabbit hole', learn assembly language. There are only seven to ten basic instructions and you can learn them in a couple of days. You can build anything you want in assembly language, if you have an eternity to do it in.

Re: Learn C The Hard Way

#54
post #39

Earlier quoted context omitted.

> You can't prove logically that the while loop inside will end given any random input . C is all about layers, and at the bottom you just assume that "all input given to this function is safe". If you're passing random input (without any error checking) to pretty much any of the built-in functions, You're Doing Something Wrong. Whether you call strcpy/copy buggy or unsafe doesn't really matter. The implementation on…

I'm going to have to side with Zed here. If I'm teaching an introductory class on Chemistry, you'd better believe that when I reach the section on cyanide I'm going to tell students: "bad, bad, bad; never use this chemical"! If those introductory students were to take a more advanced class, then I would probably tell them: "well, ok, cyanide isn't going to kill you instantly and is actually really useful for a wide r…

> If I'm teaching an introductory class on Chemistry, you'd better believe that when I reach the section on cyanide I'm going to tell students: "bad, bad, bad; never use this chemical"!

I agree. So would I. However, what Zed is doing in the last chapter is showing code written by other people. If you taught your students about an experiment done by other (widely regarded) researches, would you say "bad, bad, bad; they should never have used these chemicals"?

I would say: "See, they used it here, but only because they were very, very, very careful. Let's explore different ways this breaks down. … As you can see, I'd recommend you to not do what these people did."

Re: Learn C The Hard Way

#55
post #50
post #28

Earlier quoted context omitted.

Wrong, I make a clear example of the copy() function being broken, give a demonstration of fuzzing it to break it, and show how to do it yourself. And, if you think the copy() function is valid, then you also think strcpy() function is valid, and therefore you don't know what you're talking about. Everyone who is aware of secure C coding knows strcpy() is buggy and the cause of most buffer overflows.

First, there's no need to be aggressive. I don't really get what you're trying to say. I would understand if you said that strncat is broken (since it can output non \0 terminated strings, unlike the non-standard strlcat, breaking the principle of least astonishment) but I fail to see the problem here. It's just garbage-in/garbage-out: strcpy expects a C string, and the char array you give it is not a C string, so it…

> First, there's no need to be aggressive.

He isn't aggressive, he simply is the inimitable Zed Shaw :)

> The function has no way to detect this problem, so it's not even laziness.

His point : therefore you should not use this function, but strlcpy instead. Or course the K&R has the excellent excuse of predating about every alternative secure version of strcpy.

> Pascal strings embed the count within the string, but then you could forge a bogus pascal string with an incorrect size and trigger the same kind of problem.

I don't think that you could easily forge such a string using Pascal standard functions, but last time I wrote Pascal there was neither syntax highlighting in the editor nor hard drive in my PC.

Anyway, strlcpy should be immune, because it will truncate whatever string of bytes to the required length, see:

http://www.manpagez.com/man/3/strlcpy/

It doesn't preclude any implementation error (preperly a bug), of course.

Re: Learn C The Hard Way

#56
post #53
post #52

Earlier quoted context omitted.

>> OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? Why does a medical doctor have to learn a little bit of Latin? After all, you should be able to find all the books and material you need in your native language or at least English. C is to computing what Latin is to medicine. There's jus…

> If you're passionate about computing and software engineering, you'll have a natural interest in how things work under the hood. When I was 12, I learned 6502 assembly language. The computer I had did not have a C compiler, only BASIC or assembler (you could also enter hex into memory locations, which was hardcore). Learning assembly is actually a LOT easier than people make out. Assembly is basically mnemonics for…

> Assembly has everything a language needs for Turing completeness. Assign, Add, Subtract, Compare, Branch. And THAT is how the computer works 'under the hood'.

While what you say about Assembly is true, there's more to computer internals than doing arithmetic and control flow in the CPU. Virtual memory, DMA and IO are equally important, and the code that deals with that stuff is usually C code.

> > Learning C is almost mandatory if you want to see how deep the rabbit hole is. > Not really. I know what is going on 'down there', regardless of which language was used to compile the machine code. What is REALLY useful is to have really succinct, powerful, high-level abstractions to build software quickly and with as little code as possible.

You can book-learn what's going on under the hood but that's no replacement for getting your hands dirty. If you want to actually write code that uses memory and pointers (e.g. memory mapped files), runs in kernel mode or twiddles with page tables and virtual memory, C is the best language you can do it with.

> I think if you want to understand what's going on 'down there' in the 'rabbit hole', learn assembly language.

Learning Assembly language(s) is a very useful skill for everyone. But doing anything practical with Assembly is a futile effort, it's best to stick to C in low level stuff and resort to Assembly only when you absolutely have to. For example when you have to change between processor modes or write an interrupt handler routing, there must be some (inline) Assembly involved. But if you want to get stuff done and work with the interesting stuff, going all-assembly is not worth the effort.

I wrote a tiny multitasking operating system in Assembly. While it worked very well initially, as soon as the complexity went above one screenful of assembly, it started becoming very unwieldy. I moved on to C and got more stuff done. I could focus on the interesting stuff like scheduling algorithms and virtual memory when I didn't have the mental overhead of having to make register allocations manually or whipping up my own control structures.

Re: Learn C The Hard Way

#57
post #40

OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? I asked this question of a younger programmer the other day, because it seemed to me, that to HIM, learning C was a rite of passage, and that he was less of a man for not knowing it. I find macho philosophies in software development both amu…

Objective-C is a strict superset of C, so learning C helps a lot for any iOS or Mac programming. C++ is also heavily based on C, so it helps to learn C++. I agree C is hardly used anymore, and for good reason, but it's still interesting to learn.

The Linux kernel is in C. Large parts of the Gnome project are in C.

Re: Learn C The Hard Way

#58
post #40

OK. NOT TROLLING, but can I ask why anyone would want to learn C, other than to develop device drivers, kernel modules or other arcane software that is yet to be replaced by C++? I asked this question of a younger programmer the other day, because it seemed to me, that to HIM, learning C was a rite of passage, and that he was less of a man for not knowing it. I find macho philosophies in software development both amu…

Objective-C is a strict superset of C, so learning C helps a lot for any iOS or Mac programming. C++ is also heavily based on C, so it helps to learn C++. I agree C is hardly used anymore, and for good reason, but it's still interesting to learn.

> I agree C is hardly used anymore

Any time you want to provide libraries, you'll likely use C: all languages have C FFI, and it's not possible to have a C++ FFI. So you'd have to rely on `extern C`, and then you have to build a bunch of stuff over your OO code so it can be used procedurally.

Often not worth it, C is the lowest common denominator of languages, if you want to be accessible to all languages... you'll probably use C.

Re: Learn C The Hard Way

#59
post #48
post #41

Earlier quoted context omitted.

Not all of us see C++ as an improvement over C. Sure, C++ has great advantages, but it also great disadvantages. I use C for many things not because of "macho", but because C is good enough. I can work around the disadvantages using standard techniques. The result is code that is easily FFI'able from any language, quicker to compile, has a smaller footprint, sane error messages, easily debuggable in gdb, etc. Also, t…

Thanks for your reply. > Not all of us see C++ as an improvement over C. I know, but you are the first I've encountered to quantify it. > The result is code that is easily FFI'able from any language I agree that this is a big advantage for interoperability. While it's possible to build an interface in C++ with 'extern C', it means maintaining two call APIs rather than one. Still I see this as a current limitation of…

For the same reasons he listed above, eg you want to use an ffi etc. This is not a temporary issue with c++ as you imply, there are really hard issues about the c++ programming model, eg exceptions and classes, being really hard to interface with other languages that work differently.

The question is not why Haskell not C, sure if you can use Haskell why not, but for most use cases you cannot. But most languages can be used instead of c++, Haskell or Java or whatever, with many advantages.

Re: Learn C The Hard Way

#60
post #57

Earlier quoted context omitted.

Objective-C is a strict superset of C, so learning C helps a lot for any iOS or Mac programming. C++ is also heavily based on C, so it helps to learn C++. I agree C is hardly used anymore, and for good reason, but it's still interesting to learn.

The Linux kernel is in C. Large parts of the Gnome project are in C.

Also the GNU utilities, Apache and nginx, and the odd interpreter (Perl, Python, Ruby) or runtime system (Haskell), OpenSSL, qmail, Emacs' and vim's core, etc.

But yeah, apart from that stuff, C is hardly used.

Post reply on HN