[HN Gopher] Teaching C (2016)
       ___________________________________________________________________
        
       Teaching C (2016)
        
       Author : hasheddan
       Score  : 182 points
       Date   : 2024-01-05 23:55 UTC (23 hours ago)
        
 (HTM) web link (blog.regehr.org)
 (TXT) w3m dump (blog.regehr.org)
        
       | dfox wrote:
       | In my opinion the implementation of glibc (there is a bunch of
       | good reasons for the "weirdness" and a whole lot of gcc-isms) and
       | even the linked example from musl (with somewhat confusing #ifdef
       | block) is a thing that should be in some kind of "System
       | Programming" course, not in introductory course to C.
        
         | nicklecompte wrote:
         | The point is that the course is not introductory:
         | 
         | > I've always taught C as a side effect of teaching operating
         | systems, embedded systems, or something along those
         | lines....One might argue that we shouldn't be teaching C any
         | longer, and I would certainly agree that C is probably a poor
         | first or second language.
         | 
         | So this would be an upper-level class: an introduction to C
         | programming for people with Python/Haskell/etc experience and a
         | decent general understanding of computer science.
        
       | tialaramex wrote:
       | This has a bunch of "But what could possibly replace C?" type
       | comments and the author (writing in 2016) replies Rust. So that's
       | somebody with their eyes on the ball.
       | 
       | They also point out that C is a bad first language. This
       | shouldn't be relevant to many Computer Science courses, but I
       | have seen too many Electronics students who are taught C first,
       | or indeed as their only language.
        
         | practicemaths wrote:
         | What's wrong with C? I'm teaching myself with Ritchie at the
         | moment. Seems fine so far but I'm also more interested in
         | embedded systems.
        
           | jimbob45 wrote:
           | C++ is usually better because you can start with the
           | abstractions (e.g. new, classes, I/O streams, and strings)
           | and then work each one backwards once they're comfortable at
           | the high level.
           | 
           | (Although C++ wouldn't be my first choice to begin with for a
           | first language)
        
             | jll29 wrote:
             | Agreed, C++ is a language riddled with accidental
             | complexity, which hinders the learning process. The fact
             | that its convoluted and ever-changing syntax leads to error
             | messages that are indecipherable even for computer science
             | experts alone makes it a poor choice for learners.
             | 
             | Someone who knows nothing would benefit from Pascal a lot
             | even in 2023, even if the practical relevance of the
             | language nowadays is nil (not due to lack of merit, but due
             | to the social dynamics, as a commenter on the OP's original
             | blog righly said) - by the way, R.I.P. Niklaus Wirth. I
             | guess it would be a bit like studying Latin or classical
             | Greek to learn about grammar.
             | 
             | Python is "conceptually worse" than Scheme and Pascal - for
             | learners at an academic level, IMHO - but of course
             | practically more useful/valuable, from an industry point of
             | view.
        
           | tialaramex wrote:
           | C is a very pragmatic language for writing software on a
           | PDP-11 fifty years ago. You aren't doing that, so every
           | single place where C made compromises to facilitate that
           | you're paying a price for something you don't need or even
           | want.
           | 
           | For example you want fat pointers, particularly for slice
           | types. On a PDP-11 spending _two_ registers for these types
           | is extravagant, today this seems ridiculous, but C still
           | doesn 't provide any fat pointer types. So either you have to
           | roll your own (and with them libraries of code to use them)
           | or put up with whatever was a good idea in the 1970s. The
           | most famous slice type is Rust's &str or C++
           | std::string_view, a fat pointer for referring to text -
           | strings in other words, but not the mutable, owned, auto-
           | growing strings you might associate with higher level
           | languages, this is just the simple concept of some text. C
           | can't do that, what C gives you is a pointer to a byte,
           | pointer arithmetic and a stern admonition to stop when you
           | reach a byte with a zero value... or you can roll your own
           | slice types.
        
           | linguae wrote:
           | As a first language, a lot of students face major stumbling
           | blocks when they deal with pointers and manual memory
           | management. It's hard enough learning how to program for the
           | first time; I remember learning QBASIC as a ten year old from
           | a textbook and online tutorials. Over twenty years later I
           | had experience teaching introductory Python to absolute
           | beginners, and they have to learn how to convert problem
           | statements into code. They have to learn how simple
           | constructs such as loops and functions work. The course would
           | have been much more difficult for my students if I needed to
           | teach them about pointers and manual memory management. I
           | still remember when I first encountered C in high school, and
           | I struggled with segmentation faults due to my inadequate
           | understanding of how pointers worked. It wasn't until my
           | sophomore year of college when I finally understood pointers.
           | It was when I took a computer organization course that used
           | assembly. It was then when I had a better understanding of
           | how memory worked and how C's pointer syntax directly
           | translated to assembly.
           | 
           | I admit that I still have a soft spot for C; once I finally
           | understood pointers I did most of my projects in C; it helped
           | that I had (and still have) a love for systems programming.
           | To this day I can write C in my sleep even though it's been
           | two years since I've last written a significant amount of C.
           | But in grad school I got bit hard by the Lisp and Smalltalk
           | bugs....I went from a big Bell Labs fan to a Xerox PARC fan,
           | and in my professional career I've been largely coding in
           | Python for the past five years since it's now the lingua
           | franca of machine learning.
           | 
           | But I wouldn't recommend C as a first language; I feel it's
           | too much for absolute beginners. I'm torn between Python and
           | Scheme; my feelings right now is that Python is a good
           | introductory language for helping people gain programming
           | experience and allowing students to build interesting things
           | using Python's extensive libraries, while Scheme is an
           | excellent vehicle for teaching how programming languages work
           | at a high level; I have a soft spot for The Structure and
           | Interpretation of Computer Programs (this was the
           | introductory CS textbook at MIT from the 1980s to the late
           | 2000s when MIT switched to Python) and I used it as part of
           | an upper-division course on programming language principles
           | and paradigms at a university where Java is the introductory
           | language.
        
           | kccqzy wrote:
           | C gives you too many guns to shoot yourself in the foot.
           | Beginners deserve a language with a helpful compiler,
           | slightly more hand-holding, as well as more structure and
           | convention to encourage a maintainable coding style.
           | 
           | You can read about how experts write their C code (like
           | https://nullprogram.com/blog/2023/10/08/) but you aren't
           | going to appreciate why they decide to do this. Indeed,
           | beginners need to be able to blindly follow rules before they
           | can critique them or invent their own coding styles.
        
             | scns wrote:
             | structure returns instead of out parameters
             | 
             | typedef struct { i32 value; b32 ok; } i32parsed;
             | 
             | Defined a Result Type.
        
           | thesuperbigfrog wrote:
           | >> What's wrong with C?
           | 
           | The biggest problem with C is that it lets you do anything to
           | include things you don't want to do and should not do.
           | 
           | "The programmer knows best" means you can easily write to
           | arbitrary memory addresses, smash the call stack, allocate
           | memory and never free it, etc. and as long as the syntax is
           | correct, your program will compile.
           | 
           | Sometimes, in interesting low-level code, embedded code, or
           | similar, this unrestricted behavior is needed: you write
           | seemingly arbitrary values to a memory address because it is
           | memory-mapped hardware and that is where the control register
           | receives instructions. But in most application-level code, it
           | is bad behavior and just causes segment violations.
           | 
           | "The programmer knows best" is the primary cause of security
           | flaws in C (and C++ because of its heavy compatibility with
           | C) since even experienced C programmers make mistakes or find
           | their code being used in unanticipated ways.
        
           | hgs3 wrote:
           | > What's wrong with C?
           | 
           | It's great if you're coming from assembly language and the
           | de-factor standard for embedded systems.
        
         | genmud wrote:
         | I'm actually of the opinion that C should be taught hand in
         | hand or just after someone learns assembly. It's admittedly a
         | bit gatekeeper-y, but IMHO C should be thought of with same
         | mindset as you would develop an ASM program, but with a bunch
         | of shortcuts and syntactic sugar.
         | 
         | Without understanding what code gets generated, there are so
         | many footguns it can be dangerous at best. Knowing things like
         | calling conventions and how the compiler interacts with memory
         | are really important.
        
           | im3w1l wrote:
           | I'm of the opposite opinion. The portable-assembler camp is
           | responsible for a lot of the issues and footguns, because
           | they think they know what code will be generated. But they
           | don't. Compilers can generate any code they want, as long as
           | the program ends up doing the correct io and side effects.
           | 
           | The assembler perspective is important, but not for
           | correctness, rather for optimization. When you optimize it
           | starts mattering how much register pressure and cache
           | pressure etc you have.
        
             | genmud wrote:
             | I'm not saying because they need to understand exactly what
             | code gets generated, compiler optimizations can produce
             | interesting results. What I am saying is the idea that an
             | if statement from an assembly is a compare and a jump...
             | knowing what happens under the hood is kind of important
             | for people writing C in 2024.
             | 
             | Like I guess the point I have to make is that if you are
             | writing C in 2024, there is likely a good reason, and if
             | you don't know what's going on in the assembler, I feel
             | like people are playing with fire.
        
               | AlotOfReading wrote:
               | I think that's the misleading perspective the grandparent
               | comment is referring to. An if statement in C _isn 't_
               | necessarily a branch. The generated assembly assembly
               | might have no branches if it's eliminated, it might have
               | multiple branches, and the compiler might even include a
               | function call (e.g. fharden-conditional-branches). You
               | can't know just by looking at the source code alone.
               | 
               | I've found that I'm much less accurate when writing code
               | for non-GCC/Clang compilers because my mental model of
               | what's going to be generated isn't accurate enough
               | without the years of experience I've had looking at the
               | outputs of those specific compiler families.
        
               | uecker wrote:
               | While true, compared to some of the other languages C
               | code is still relatively close to source, e.g. it will
               | not completely change your data types behind your back
               | etc.
        
             | lifthrasiir wrote:
             | I do resonate with your comment a lot, but the portable
             | assembly aspect also drove much of the current C use. As a
             | compromise we may teach _two_ quite different architectures
             | and ask students to write a single code that runs in both.
             | This way they can avoid false beliefs like `sizeof(int) ==
             | 4` and hopefully still learn common aspects of most
             | architectures that shaped C 's design.
        
           | ranger207 wrote:
           | I agree. I learned this way, and, for example, wrapping my
           | head around pointers was much easier after I already
           | understood why LEA existed. Yes, C isn't portable assembler,
           | and no, you can't necessarily predict what ASM will be
           | produced from a particular snippet of code. However, C
           | operates closer to "portable assembler" than any other
           | programming language, and it's a lot harder to go from
           | anything else to C than it is to go from assembly to C
        
       | alilleybrinker wrote:
       | It's not mentioned in the article, but I also think that learning
       | how to debug and observe the behavior of C programs is useful
       | given the limited ability to catch issues at compile time and
       | high likelihood of code weaknesses and errors in C. Learning not
       | just a traditional debugger like gdb or lldb, but also at least
       | being introduced to tools like perf, strace, and ideally more
       | powerful things like dtrace or bpftrace would be very helpful.
       | 
       | In my own Masters program we had a class on software systems
       | which heavily featured both practical coverage of C and lots
       | about debugging and observability. One of the most aggressively
       | _useful_ classes I've taken.
        
         | clipsy wrote:
         | This sounds like a class that was sorely missing in my CS
         | education; looking back at what I was taught versus what skills
         | have been useful in the industry, my university courses always
         | seemed to treat debugging, profiling, etc as irrelevant
         | details. Taking time to improve my understanding of them has
         | paid off quite well in my career, I think.
        
           | pjmlp wrote:
           | Yes, the poor way this is taught is one of the reasons why so
           | many people are stuck in the stone age of printf debugging.
           | 
           | Already in the mid-1990s it was possible to use C debuggers
           | as poor man's REPL, have tracepoints, scripting debugging
           | sessions, visualize data structures, track down memory leaks
           | and corruption.
        
           | einpoklum wrote:
           | Years ago, I was a teaching assistant at my alma mater's
           | introductory programming course, which taught C. While
           | debugging was not officially part of the curriculum, we made
           | sure to offer a written, step-by-step tutorial with
           | screenshots for people on how to do debugging using our
           | officially-suggested development environment (which was
           | Borland C by the way). We would explicitly mention the
           | importance of debugging when introducing the first homework
           | assignment, and refer students to the tutorial.
        
       | chrsw wrote:
       | A few good C books have come out in the time since this article
       | was first published, 2016.
       | 
       | https://nostarch.com/Effective_C
       | 
       | https://www.packtpub.com/free-ebook/extreme-c/9781789343625
       | 
       | https://www.oreilly.com/library/view/fluent-c/9781492097273
        
         | johnisgood wrote:
         | I have found https://www.manning.com/books/modern-c really
         | useful.
         | 
         | It is written by Jens Gustedt
         | (https://icps.icube.unistra.fr/index.php/Jens_Gustedt)
        
       | nickpsecurity wrote:
       | I wrote a lot of criticism of C here. I do want to say the K&R
       | book was a great read when I finally did some hands-on work with
       | C. Credit to Victor Yodaiken for recommending it.
       | 
       | The explanations were well-done. They gradually build up the
       | examples. They actually did warn about common gotchas even then.
       | Their examples mostly worked today with only minor tweaks. I used
       | it with Clang's and MS Visual Studio's static analyzers.
        
       | TrackerFF wrote:
       | When I studied, C was the first language we learned. I think it
       | was a great way, as we'd learn about memory management, how to do
       | things from "scratch", and since there weren't many batteries
       | included, we kind of just implemented data structures and
       | algorithms as we went on.
       | 
       | It also primed us for more involved classes, like operating
       | systems, compilers, databases, and so on.
       | 
       | But I have to say, it is a language that students really need to
       | fundamentally know if it is going to be used down the road.
       | Sounds obvious, but when I TA'd in more advanced classes (i.e.
       | anything after "introduction to programming"), many of the
       | students that were struggling, were really just struggling with
       | the language - not necessarily the CS concepts. A lot of them
       | were even students that had programming experience prior to
       | enrolling, but had mostly used higher level languages.
        
       | puzzledobserver wrote:
       | Wouldn't a better first question be _why_ we're teaching students
       | C?
       | 
       | One answer might be that although students might spend most of
       | their later professional lives in higher-level languages, they
       | should have some experience in a low-level language.
       | 
       | The ideal such language would not have memory management (i.e.,
       | not Java / Python), no memory management help from the type
       | system (so no Rust), and no fancy facilities to build
       | abstractions (so no Rust or C++). This language should, ideally,
       | still be a little more pleasant to work with than assembly (so,
       | no assembly). For historical reasons, we would still like
       | unchecked array accesses and null-terminated strings.
       | 
       | Now C is an answer to this question, but it need not be the only
       | answer. We could instead teach students a fictionalized version
       | of real C. So nice 2-s complement behavior on overflows, buffer
       | overflows segfaults and other bad behavior, but mostly of the
       | predictable kind. We could define undefined behaviors as the
       | instructor sees fit.
       | 
       | As much as we can, we can try to make this fictionalized language
       | agree with the semantics of gcc -O0. We can then study gcc -O0 -S
       | itself as an empirical artifact, and use it to understand
       | x86/x86-64/ARM/MIPS assembly.
       | 
       | Finally, while we're at it, we can use the Bourbaki dangerous
       | bend symbol
       | (https://en.wikipedia.org/wiki/Bourbaki_dangerous_bend_symbol) to
       | repeatedly remind students that what they're studying isn't a
       | real language, that real C has sharp edges (including undefined
       | behaviors), and that things like ASAN / Valgrind / ... exist.
       | 
       | I worry that this article is confusing that we'd like students to
       | eventually understand (some understanding of C and an
       | appreciation of the fact that it is an important language which
       | still needs to be handled with care) with the didactic process of
       | reaching that understanding. Wittgenstein's ladder is a thing.
        
         | yjftsjthsd-h wrote:
         | If we went to the trouble of making a safe version of C - and
         | we would have to actually implement it; you can't very well
         | teach students to program without letting them actually compile
         | the code and run it - I'd rather just... use that. Call it C24,
         | get it into GCC and Clang, and standardize on something with
         | less Undefined Behavior and painful sharp edges.
        
         | saagarjha wrote:
         | Because teaching students a fictional version of C does not
         | prepare them well for dealing with actual C.
        
           | lifthrasiir wrote:
           | It is not like that instructors are necessarily good at
           | actual C, not alone teaching C though.
        
         | akira2501 wrote:
         | I feel like you're trying to merge computation as a science
         | with an idealized language choice and I don't think it would
         | serve students well.
         | 
         | The "sharp edges" of C in either user mode or kernel mode when
         | running on an x86 or arm platform are true implementation
         | semantics that you must deal with while trying to realize
         | genuine "computation."
         | 
         | Programming languages are just collections of human shorthand
         | for managing these semantics. Which makes me feel that
         | inventing this language would be putting the cart before the
         | horse.
        
         | pjmlp wrote:
         | Because some of those students will eventually have to maintain
         | systems written in C, that unfortunately will never be written
         | into something else.
        
       | 6R1M0R4CL3 wrote:
       | we should all learn C and in time, go help that kernel project
       | some of you might have heard of...
        
         | ptek wrote:
         | Agreed, I'd like to be skilled enough to contribute and add
         | some more drivers to NetBSD or NextStep 3.3/OpenStep
         | 4.2/Rhapsody DR2 (Objective C)
        
       | keyle wrote:
       | I love C. It's the language that makes me the most happy. I'm not
       | entirely sure why, I think I like being in control. People always
       | comment about C is unsafe, full of razors and knives flying
       | around.
       | 
       | The thing to keep in mind is that *you* are the one throwing the
       | razors and knives from the moment you go beyond printf("hello,
       | world!\n");
       | 
       | I'd never recommend a company to start building anything in C. In
       | term of the various team sizes and staff churn over the lifetime
       | of a company, it's too risky.
       | 
       | But afaik most companies, particularly the growth hacking ones,
       | are either Go or Kotlin or at that level of abstraction. Rust is
       | slowly eating at C++ and I'm pretty sure no company in their
       | right mind today start a new product in C++. It will slowly
       | become COBOL.
       | 
       | C on the other hand still has new C written every day. I'm a
       | polyglot and I love C, but I never had a job in C. I hope some
       | day that happens. The modern tools aforementioned, e.g. static
       | analysis, clangd, are really good.
       | 
       | The thing I love most about C is that there is a direct
       | relationship between me doing something stupid and feeling pain
       | for it. In python, I can write crap all day without feeling it.
       | Some day I'll feel it, but not today!
       | 
       | I like small binaries and fast code. I like that when a developer
       | tells me I did something wrong, they can prove it, and it's not
       | some stupid high level language "the more you knoooow". I like
       | control over things.
       | 
       | I love modern C and I wish it well!
        
         | epcoa wrote:
         | > I'm pretty sure no company in their right mind today start a
         | new product in C++.
         | 
         | The library support for rust in key areas is terribly lacking
         | and not everyone is a Microsoft that can afford to build the
         | world from scratch.
         | 
         | As just one example a few valiant folks develop plugins and
         | realtime audio with rust, but serious work that needs to get
         | done today happens in C++.
        
         | 3a2d29 wrote:
         | > I'm pretty sure no company in their right mind today start a
         | new product in C++
         | 
         | I say this as someone who loves rust and zig, but these types
         | of statements make me feel like HN is way out of touch with the
         | industry. New products are constantly made in C++. That doesn't
         | make it good (and i don't think companies building in C++ are
         | making the best choices), but to say that no big tech company
         | is writing any new code in C++ is just not correct. I see this
         | happen every day at my job.
         | 
         | I also would definitely say more C++ code is written every day
         | over C, although I'll say, I am not as familiar with the
         | embedded world, but I know one HFT/Gaming/Robotics firm will
         | have millions of new C++ lines every day.
        
           | hansvm wrote:
           | > in their right mind
        
         | jakogut wrote:
         | Agreed, I also like writing and especially reading (good) C.
         | The Linux kernel, Wine, and FFmpeg are a joy to read, and much
         | more approachable than one would think.
         | 
         | I get exhausted by people denouncing C in favor of the language
         | du jour, and suggesting it's been obsoleted by newer and
         | especially more abstract languages. A hammer and nails are
         | still useful for specific jobs, even if you have screws.
         | 
         | All tools have their trade offs. Even when you have a battery
         | powered impact driver, sometimes you still need to pick up a
         | basic hammer.
        
         | saagarjha wrote:
         | > I'm a polyglot and I love C, but I never had a job in C. I
         | hope some day that happens. The modern tools aforementioned,
         | e.g. static analysis, clangd, are really good.
         | 
         | If you had a job in this you'd know that they are not ;)
        
         | bsdpufferfish wrote:
         | > staff churn over the lifetime of a company, it's too risky.
         | 
         | Experience says otherwise. C code bases have serious longevity
         | due to how many people know it and can jump in and contribute.
         | There just aren't that many patterns and abstractions.
        
         | dvko wrote:
         | > I love C.
         | 
         | You and me both. I'm also a polygot but I originally started on
         | interpreted languages like PHP and Python. I then learned some
         | C, which was quite frustrating before I learned how to reason
         | about memory ownership and hold myself to some idioms. Oh and
         | Valgrind.
         | 
         | I then rewrote a bunch of projects in Rust and while it lead to
         | correct and working software, it didn't spark the joy that C
         | did for me. I don't exactly know why and at times I almost feel
         | ashamed to mention this. I do hope there's a future where
         | there's a version of C with some more substantial
         | changes/improvements though, perhaps taking a lesson or two
         | from Rust or Zig (eg string type w/ length).
        
           | jll29 wrote:
           | Since D is already taken, maybe a language called "E"?
           | 
           | The first thing I'd borrow from Rust are Option and Result
           | for better error handling.
        
             | keyle wrote:
             | Yes, this, most modern languages embrace this idea of
             | Optional. I believe OCaml might have invented it (I love
             | OCaml too!). Odin has it I think, Rust obviously, and Swift
             | heavily as well.
             | 
             | What's interesting, modern C, is promoting this move as
             | well. Don't just return an integer, return a struct
             | result_t with a fail bool or error bool in it, as opposed
             | to some const char* pointing to null. Do this more and more
             | and your C code starts becoming a lot more digestible and
             | modern (although common sense still applies to not go
             | overboard with these constructs in C, but you can set up a
             | nice contract type API design within your code base).
        
         | sgbeal wrote:
         | > The thing I love most about C is that there is a direct
         | relationship between me doing something stupid and feeling pain
         | for it.
         | 
         | Excellent! Such wisdom is rarely found in random forum threads
         | on the internet.
        
         | Keyframe wrote:
         | I'm in the same boat. Took me a while to accept that I am a C
         | programmer at heart, it suits me the best. I feel like I'm in
         | full control and I can move fast with it. Not all razors are on
         | us though, especially if moving around compilers since there
         | are here and there undefined behaviour parts and it's easy to
         | throw knives around.
         | 
         | I also wouldn't recommend starting a new thing with it if the
         | whole team wasn't well-versed with it. On the other side of
         | spectrum, today's world is well-served with python, c++ and
         | rust (that battle is ongoing, I like both), java, heck even JS.
         | There's something special about C though and I've yet to see
         | something replacing it's place. Closest was D1, but that came
         | and went.
        
         | uecker wrote:
         | In my opinion, companies should consider C for new projects.
         | Many people know it, the tooling is excellent, there is long-
         | term stability, compile times are fast. With other languages
         | you run into constant problems with tooling or compatibility
         | issues. Also in my experience average and unexperienced
         | programs can be very productive in C. Even if the code is not
         | perfect, it can often be improved incrementally, where in some
         | other languages I sometimes decided to throw it away because
         | there abstractions that do not make sense and everything
         | depends on it. But one absolutely needs to exploit good coding
         | guidelines, modern tools, and CI, and avoid low-level pointer
         | fiddling or string manipulation (which can be abstracted away
         | in C as well as in other languages). Some of the most reliable
         | and powerful software I use daily is written in C.
        
       | WalterBright wrote:
       | I was an experienced asm programmer before a friend loaned me a
       | copy of K+R C. I understood C immediately. I imagine trying to
       | learn C without knowing assembler would be a much tougher road.
       | 
       | Knowing C also helps in understanding a lot of other languages.
        
         | ykonstant wrote:
         | Your comment prompted me to submit the following question at
         | reddit:
         | 
         | https://www.reddit.com/r/learnprogramming/comments/18zz72t/d...
         | ?
         | 
         | If you know of a better place to ask such questions, let me
         | know.
        
         | pjmlp wrote:
         | Same here although coming from multiple languages, so C was
         | only another syntax to do the same things I was already doing
         | in those languages.
         | 
         | As such I never understood what is so hard about pointers, we
         | were already close friends before learning C.
        
       | dang wrote:
       | Related:
       | 
       |  _Teaching C (2016)_ -
       | https://news.ycombinator.com/item?id=32798826 - Sept 2022 (94
       | comments)
       | 
       |  _Teaching C (2016)_ -
       | https://news.ycombinator.com/item?id=18334476 - Oct 2018 (211
       | comments)
       | 
       |  _Teaching C_ - https://news.ycombinator.com/item?id=11668396 -
       | May 2016 (152 comments)
        
       | anta40 wrote:
       | >> adding some high-quality C code, perhaps starting with Redis,
       | Musl, or Xv6.
       | 
       | Agree. Xv6 is the reason why I used C. I learnt more about
       | various OS concepts (process scheduling, file system etc) by
       | hacking Xv6 code. Linux is too complicated for my taste.
       | 
       | As a mobile app dev, I don't use C. Well.... I do. Very
       | ocasionally though. Only for interacting with specific Android
       | hardwares.
        
       | beyonddream wrote:
       | I have been programming in C professionally for the past ~4 years
       | on a multi-threaded application in the ads industry and that is
       | central to the business. C has lot of documented "foot-guns" but
       | most of it (if not all of it) can be safeguarded against mis-use
       | using "support structures" around the codebase like having
       | standard code style (enforced via tools as much as possible),
       | static code analysis (via compiler and external code scanning
       | tools), dynamic code analysis (via Asan, Ubsan etc), having
       | small, medium and large tests with right amount of code coverage
       | etc. In addition to that, having a standard set of libraries (c
       | modules for high performance data-structures/algorithms, macro
       | based templates to work with types) and threading model goes a
       | long way in reducing the pain to a very bare minimum. On the plus
       | side, you enjoy a "simpler" language syntax that is easy to learn
       | and with the above "support structures" one can become productive
       | in no time. Plus there are newer books in the market that can
       | teach you C properly, one I have read and recommend is "Effective
       | C by Robert C. Seacord" - the author is one of the C standards
       | committee members so you can't go wrong with the choice.
        
       | countWSS wrote:
       | Many people complain about teaching C leading to bad habits or
       | something of that sort. C is crucial to understanding OS apis,
       | driver code and low-level algorithms, its not locked to single
       | platform like assembly and allows composing fairly high-level
       | abstractions without any hidden overhead. Writing your own libc
       | functions and understanding how they work is essential to systems
       | programming.
        
         | lifthrasiir wrote:
         | The complaint is probably more about teaching C _too early_ and
         | getting fixated on that. The importance and eventual need for
         | learning C is hardly questioned.
        
         | pjmlp wrote:
         | The problem is not teaching C, for better or worse it is going
         | to stay around us for a very long time, thanks to UNIX's
         | victory on server room and embedded systems.
         | 
         | The actual problem is doing a half baked job, teaching it as if
         | PDP-11 were still current, without any consideration for safe
         | programming practices and modern tooling.
        
         | sys_64738 wrote:
         | These bad habits you mention should be taken care of by general
         | programming concepts classes. If you're using a new language
         | like C for OS development and you are thinking of goto and
         | other frowned on methods then a person really didn't do the
         | programming concepts class very well.
        
       | prudentpomelo wrote:
       | >> There's a lot of reading material out there. For the basics, I
       | still recommend that students purchase K&R.
       | 
       | Has anyone read K&R and regretted it? I am working through all
       | the exercises and have really enjoyed the process.
        
       | heads wrote:
       | The thing that really got me into this subject was building my
       | own virtual machine and then a compiler to turn a high level
       | language into machine code.
       | 
       | It sounds complicated but the VM, in Python, is basically:
       | r = {}       mem = []       boot(mem)       pc = 0       while
       | True:         op, args = decode(mem[pc++])         if op == "+":
       | d, a, b = args           r[d] = r[a] + b         elif ...:
       | ...
       | 
       | The "source" which gets "compiled" can also just be Python
       | function calls that emit op codes -- no need to get bogged down
       | with lexing and parsing!
       | 
       | The thing you focus on is the semantics of representing a
       | function call (and return) in machine code and how to manage the
       | stack. It made C make a lot more sense e.g. defining locals up
       | front so the compiler knows how much stack space to use. I wish I
       | could remember more -- this was all from teaching A-Level
       | Computer Science a few years ago.
        
         | samsquire wrote:
         | Agreed.
         | 
         | I find C easier to understand than the algebra of other
         | languages such as Haskell, Ocaml, Rust because of how C
         | statements correspond to assembly.
         | 
         | Memory is just a big grid of numbered locations and computing
         | is logistics between grid locations. Execution is transition
         | between memory locations.
         | 
         | LEAQ or "&" (C addressof) is an address calculation or LEAQ for
         | one of those grid locations.
        
           | IshKebab wrote:
           | > C statements correspond to assembly
           | 
           | True in the 80s maybe. Not remotely true now.
        
             | samsquire wrote:
             | I don't mean that there is a 1-1 constant relation between
             | C statements and exact assembly, but if you run gcc with -S
             | or run                  objdump -b binary -Matt,x86-64 -D
             | main.bin -m i386 ;
             | 
             | (note: this command places the assembly and C code side
             | next to eachother, I think you have to compile with -g
             | debug flag with gcc)
             | 
             | You can work that the assembly implements the semantics of
             | C's virtual machine model and it is this that I find easier
             | to understand than some algebraic systems. I kind of think
             | of struct->ptrarray[indx]->struct.something corresponds to
             | the calculation of ultimately a single memory address even
             | if there is various shift lefts or adds or ors.
             | 
             | Java has its template interpreter which is interesting to
             | read about and there is copy and patch JIT compilers.
        
               | pjmlp wrote:
               | You can do the same in any compiled language, including
               | Java.
               | 
               | Sun's Forte Pro was one of the first IDEs to have such
               | capability for Java.
        
               | IshKebab wrote:
               | Sure but the relationship between assembly and source
               | lines can be very complicated, even for trivial code:
               | 
               | https://godbolt.org/z/hjW4T934q
               | 
               | And that capability is not remotely unique to C - look at
               | the list of languages Godbolt supports! Not all of them
               | support linking source code to assembly but a large
               | number do: C++, Rust, Zig, Ada, even Dart.
        
               | IshKebab wrote:
               | I don't think the correspondence between C and assembly
               | is really significantly higher than Rust, Zig or even Go.
        
       | sgbeal wrote:
       | > A stronger tool such as the Clang static analyzer should also
       | be used.
       | 
       | While also teaching students that static code analyzers are very
       | far from infallible and can waste a great deal of developer time
       | with false positives.
       | 
       | It happens about once every month or two that someone posts on
       | the sqlite forum, "I've found this serious bug..." and, after
       | some back and forth, it's revealed that they used a static
       | analyzer or, even worse, just pasted a single internal function
       | from the sqlite core into ChatGPT and asked it to analyze the
       | code for them (completely free of any calling context). Roughly 9
       | times out of 10, static code analyzers are flat out wrong in
       | their analysis of that particular source tree. It's very rare
       | that a report in sqlite which stems from a static code analyzer
       | is actually correct.
       | 
       | The advice given to such posters is invariably: if you can
       | demonstrate code which tickles the bug your tool is claiming to
       | have found, it will be treated with priority. Until then... not
       | so much.
        
         | ahoka wrote:
         | Coverity used to suggest using strncpy instead of strcpy for a
         | while, which if you blindly follow leads to nasty errors. If
         | someone wonders, snprintf was the correct alternative at the
         | time, I have no idea if the C standard has anything better now.
        
       | DrNosferatu wrote:
       | No mention of the Deitel & Deitel books?
        
       | toasted-subs wrote:
       | I feel like very rarely do u feel as satisfied as when I program
       | in C.
        
       | anthk wrote:
       | If you are a seasoned C programmer, helping GNU Hurd, for
       | instance, with the Rump kernel addon to add NetBSD driver support
       | (please, no blobs) would be a good thing to have.
       | 
       | https://www.gnu.org/software/hurd/
       | 
       | You can debug drivers on the fly with gdb, something much more
       | difficult to do under OpenBSD, NetBSD and Linux-(libre).
       | 
       | Also, you can run Hurd inside Hurd, a la chroot. But no root
       | permissions are needed.
       | 
       | https://www.gnu.org/software/hurd/community/gsoc/project_ide...
       | 
       | Yep, C is the Unix and Unix-like ABI, and an odd form of C it's
       | under 9front/plan9's ABI/API too, but this makes the userland
       | much more powerful than the typical permission-isolated Unix
       | system where the user has near no capabilities even for mounting
       | non-external media (by default).
        
       | flohofwoe wrote:
       | One thing I would try to do (in addition to the things mentioned
       | in the article) is to delay the introduction of heap allocation
       | and pointers as much as possible, and start with a purely "value
       | based" code style which passes and returns structs by value,
       | especially use C99 features like compound literals and designated
       | initialization. The result is a much saner and 'friendlier' C.
       | 
       | Also ignore the stdlib as much as possible, especially the string
       | functions.
       | 
       | The C stdlib APIs are essentially ancient leftovers from the K&R
       | and early C89 era and should have been modernized when C99 came
       | around. Especially for newbies, paying too much attention to the
       | stdlib may ingrain bad habits.
        
         | mi_lk wrote:
         | what should be the replacement for C stdlib?
        
           | hgs3 wrote:
           | The stdlib is mostly fine. The string and character
           | classification functions are outdated because they aren't
           | Unicode aware. There's a more detailed write up here [1].
           | 
           | [1] https://nullprogram.com/blog/2023/02/11/
        
             | flohofwoe wrote:
             | It's not just the missing UNICODE support (although that's
             | probably out of scope for the stdlib, a couple of UTF-8
             | aware helper functions would be good enough), but footguns-
             | in-waiting like strcpy(), strncpy(), strcat(), strncat(),
             | ...
             | 
             | All the wide string stuff (wchar.h and wctype.h) as well as
             | locale.h is all pointless today.
             | 
             | Everything related to filesystems and file IO is just the
             | bare minimum that's acceptable for simple UNIX-style
             | command line tools, but not really useful in modern
             | applications (most notably, any support for non-blocking IO
             | and memory-mapped-files are missing).
             | 
             | Arguably, complex.h doesn't even belong in the stdlib (I
             | wonder why such an esoteric feature was even considered).
             | 
             | Better support for custom allocation strategies would be
             | nice (e.g. each function which allocates under the hood
             | should accept an allocator argument instead of being
             | hardwired to malloc).
             | 
             | I'm not even asking for a more feature-rich stdlib, a
             | stdlib2 with the obsolete parts removed and modernized IO
             | and memory management functions would go pretty far. But
             | then of course there's the problem that the C stdlib is
             | also accidentially the de-facto system API on some UNIXes.
        
               | mattpallissard wrote:
               | > any support for non-blocking IO and memory-mapped-files
               | are missing
               | 
               | Sure but POSIX supports that and it may as well be the
               | stdlib for those of us in *nix land.
        
           | flohofwoe wrote:
           | There isn't a proper universal solution unfortunately apart
           | from looking for 3rd-party-libs which provide better
           | abstractions over the underlying OS APIs (or writing those
           | yourself).
        
       | jll29 wrote:
       | After programming already for many years, the book "C: Interfaces
       | and Implementations" by Hanson still showed me some new tricks
       | for writing libraries in a more bullet-proof way, and I have
       | mentioned or used it in every C course I have taught ever since.
       | 
       | The book contains some production-quality data type
       | implementations that aspiring C programmers ought to read.
        
       | sys_64738 wrote:
       | Their approach is wrong. You don't say at a university level that
       | you're going to teach C in a class. That's not what university
       | level courses are about. If you're teaching programming
       | applications and techniques then use a relevant language which
       | supports those concepts. Learning a language should be a bi-
       | product of the university course, not the fundamental reason for
       | it. You learn C as part of any myriad of courses such as
       | networking, but then it is simply a lecture or two then students
       | need to get up to speed themselves.
        
       | InvOfSmallC wrote:
       | I'm a contract professor at uni. I think that he should put which
       | kind of students you are teaching C to.
       | 
       | I am their first experience at university and for some of them C
       | us their first programming experience.
       | 
       | In this case my only advice is just keep repeating the same
       | subject in more than one lesson.
       | 
       | What is suggested into the article seems to me more about "how do
       | I run C in production".
       | 
       | But good suggestions anyway, I'll review them to see what I could
       | use if it makes sense maybe when we do lab.
        
       ___________________________________________________________________
       (page generated 2024-01-06 23:02 UTC)