Live data from Hacker News

To become a good C programmer (2011)

fabiensanglard.net

101–110 of 135 posts

Re: To become a good C programmer (2011)

#101

Why does everyone always suggest K&R? I really don't see the big deal. It's short, contains only trivial toy examples with no real world application, and touches almost nothing on actual project architecture or best practices. I bought it expecting to learn to write programs in C but it's really just a reference manual on syntax.

> trivial toy examples with no real world application

It teaches you how to write malloc. Plenty of the examples have real world applications. If you want a book on architecture then get a book on architecture. K&R is about C.

Re: To become a good C programmer (2011)

#102

Interesting comment they made about using C89 for portability. What's the state of C99 today? I know gcc doesn't support all C99 features, but what about other compilers? Is it worthwhile to use C99 in a new project?

C99 is well supported now, but Its has become increasingly clear that some of the changes to the definition of undefined behavior in the spec has made som very troubling compiler optimizations possible that can make C a lot less dependable. Later versions of C also adopt a new memory model that is very broken. memcopy is for instance impossible to implement in C17. Due to these issues the Linux kernel is no longer us…

> Later versions of C also adopt a new memory model that is very broken.

You mean, adopting a memory model that properly supports multi-threaded code?

> memcopy is for instance impossible to implement in C17.

What? I assume you mean memcpy? How is it impossible to implement given that it's implemented in the standard library?

> Due to these issues the Linux kernel is no longer using standrard C.

As others have mentioned, the Linux kernel never used standard C. Just search for, say, the substring "__builtin" where it uses compiler builtins directly. It's also quite recent that Linux can be compiled by clang; if it were using standard C, such compatibility issue would not arise in the first place.

Re: To become a good C programmer (2011)

#103

I think for us laymen, the most difficult thing is to find a good reason to use C frequently. I have a few "legitimate" (in the sense that C is actually suitable for those) non-embedded projects that I'd like to take on in the future when I have time to pick up C: 1 - Recreate some of the Linux command line tools, including a command line interface similar to BASH; 2 - Implement a fully functional compiler or byte-co…

A lot of widely used recent CLIs have been implemented in Go or Rust, e.g. I don't think I would choose C for such a task these days.

https://github.com/BurntSushi/ripgrep

https://github.com/sharkdp/bat

https://github.com/jesseduffield/lazydocker

https://github.com/ogham/exa

https://github.com/docker/cli

https://github.com/cli/cli

Re: To become a good C programmer (2011)

#104
post #88

Earlier quoted context omitted.

Then there’s the perennial problem of missing format specifiers for POSIX types like pid_t. Although you could argue that POSIX should mandate macros to appropriately handle them, the root problem is the same. The default integer types have not aged well...

> missing format specifiers for POSIX types like pid_t This bothers me less because I can always cast it up: fprintf(logfile, "pid: %lld", (long long)pid); Technically not portable, but find a platform with PIDs where this breaks. You can count on long long being at least 64 bits, and I think it'll be a while before we need 128 bit process IDs. :-) > The default integer types have not aged well... To me, the real pis…

On Amiga, long was 32 bit and int 16 bit and that was a long time ago, when Microsofts int was also 16 bit. So they already shifted it up once. (Going from DOS to Win32 I guess.)

Re: To become a good C programmer (2011)

#105
post #22

In the 90s, most seriouc C programmers knew about these books. They were the core books most devs relied on and referred to. They're all good. I disagree with this comment: "No website is as good as a good book. And no good book is as good as a disassembly output." There are many websites today that are excellent. And there are many websites that cover obscure topics not found in books. Finally, I think it's importan…

> And there are many websites that cover obscure topics not found in books. Yup. Are there any books covering the same content that ctyme does? ( http://www.ctyme.com/intr/int.htm )

Ah, the famous “Ralph Brown’s Interrupt List”. It was actually published as a book: https://www.amazon.com/PC-Interrupts-Programmers-Reference-T...

Re: To become a good C programmer (2011)

#107

Earlier quoted context omitted.

It supports most of it. Useless stuff like VLA is still uninmplemented though.

Why is VLA useless? Why was it added to C99?

Because even C isn't free from the occasional misfeature slipping into the standard. VLAs come with a lot of caveats (e.g. available stack size being limited and opaque, no sizeof() support, etc).

VLAs were made optional in C11, so it's better not to use them at all for portable code.

Re: To become a good C programmer (2011)

#108
post #19
post #17

Earlier quoted context omitted.

> But today, there is little reason for most projects not use the advances found in C99. Does visual studio support c99 yet? Last I heard MS wasn’t interested in supporting it.

Really? No longer an MS user but occasionally my code gets ported to Windows so would like to know more.

The only notable C99 features not supported on the MSVC C compiler are: (a) VLAs, and (b) type-generic macros. The distinction between the MSVC C and C++ compiler is important though. The MSVC C++ compiler doesn't support any C99 features.

Re: To become a good C programmer (2011)

#109
post #102

Earlier quoted context omitted.

C99 is well supported now, but Its has become increasingly clear that some of the changes to the definition of undefined behavior in the spec has made som very troubling compiler optimizations possible that can make C a lot less dependable. Later versions of C also adopt a new memory model that is very broken. memcopy is for instance impossible to implement in C17. Due to these issues the Linux kernel is no longer us…

> Later versions of C also adopt a new memory model that is very broken. You mean, adopting a memory model that properly supports multi-threaded code? > memcopy is for instance impossible to implement in C17. What? I assume you mean memcpy? How is it impossible to implement given that it's implemented in the standard library? > Due to these issues the Linux kernel is no longer using standrard C. As others have mentio…

The new memory model tried to make it possible to implement fat pointers with reference counters. That means that the compiler must be able to tell when a pointer is being copied. After the spec was ratified several people pointed out that its not possible to implement memcpy(typo sorry) since memcpy doesn't know what it is copying and might therefore copy a pointer without increasing the ref counter.

Re: To become a good C programmer (2011)

#110
post #54

Earlier quoted context omitted.

C99 is well supported now, but Its has become increasingly clear that some of the changes to the definition of undefined behavior in the spec has made som very troubling compiler optimizations possible that can make C a lot less dependable. Later versions of C also adopt a new memory model that is very broken. memcopy is for instance impossible to implement in C17. Due to these issues the Linux kernel is no longer us…

> Due to these issues the Linux kernel is no longer using standrard C. The Linux kernel never used standard C, since the very first release (0.01) it already depended on GCC extensions.

It has always used extensions to do things like lin line assembler, something you need when writing an operating system. What has changed is that compiler writers now interpret the new spec language in some ways that Linus thinks are broken, due to the new definition of UB. Like this:

void set_value_to_zero(int * p) { if(p == NULL) throw_an_error_and_exit(); *p = 0; }

In c89 writing to NULL is gives you undefined behavior. In c99 the compiler can assume that no code path will produce code that writes to NULL. That's a huge difference! It means that looking at the above code the compiler can reason: since there is a path to writing to the pointer p, the compiler can assume that p will never be NULL. Therfore p == NULL is known to be FALSE at compile time and the null test can be optimized out. I (and Linus) think this is insane.

Post reply on HN