Live data from Hacker News

Everything I wish I knew when learning C

tmewett.com

71–80 of 401 posts

Re: Everything I wish I knew when learning C

#72
I like it, but the array details are a little bit off. An actual array does have a known size, that's why when given a real array `sizeof` can give the size of the array itself rather than the size of a pointer. There's no particular reason why C doesn't allow you to assign one array to another of the same length, it's largely just an arbitrary restriction. As you noted, it already has to be able to do this when assigning `struct`s.

Additionally a declared array such as `int arr[5]` does actually have the type `int [5]`, that is the array type. In most situations that decays to a pointer to the first element, but not always, such as with `sizeof`. This becomes a bit more relevant if you take the address of an array as you get a pointer to an array, Ex. `int (*ptr)[5] = &arr;`. As you can see the size is still there in the type, and if you do `sizeof *ptr` you'll get the size of the array.

Re: Everything I wish I knew when learning C

#73
post #55

> Declaring a variable or parameter of type T as const T means, roughly, that the variable cannot be modified. I would add "... cannot be modified through that pointer ". (Yes, in fairness, they did say "roughly".) For example consider the following: void foo(int* x, const int* y) { printf("y before: %d\n", *y); *x = 3; printf("y after: %d\n", *y); } This will print two different values if you have `int i = 1` and yo…

A small detail: you probably meant printf("y before: %d\n", *y);

Oops you're right! Fixed now thanks.

Re: Everything I wish I knew when learning C

#74
> Everything I wish I knew when learning C

By far my biggest regret is that the learning materials I was exposed to (web pages, textbooks, lectures, professors, etc.) did not mention or emphasize how insidious undefined behavior is.

Two of the worst C and C++ debugging experiences I had followed this template: Some coworker asked me why their function was crashing, I edit their function and it sometimes crashes or doesn't depending on how I rearrange lines of code, and later I figure out that some statement near the top of the function corrupted the stack and that the crashes had nothing to do with my edits.

Undefined behavior is deceptive because the point at which the program state is corrupted can be arbitrarily far away from the point at which you visibly notice a crash or wrong data. UB can also be non-deterministic depending on OS/compiler/code/moonphase. Moreover, "behaving correctly" is one legal behavior of UB, which can fool you into believing your program is correct when it has a hidden bug.

A related post on the HN front page: https://predr.ag/blog/falsehoods-programmers-believe-about-u... , https://news.ycombinator.com/item?id=33771922

My own write-up: https://www.nayuki.io/page/undefined-behavior-in-c-and-cplus...

The take-home lesson about UB is to only rely on following the language rules strictly (e.g. don't dereference null pointer, don't overflow signed integer, don't go past end of array). Don't just assume that your program is correct because there were no compiler warnings and the runtime behavior passed your tests.

Re: Everything I wish I knew when learning C

#75

‘ You can’t extend structs or do anything really OO-like, but it’s a useful pattern to think with’ That’s not quite true. If you define 2 structs so that they start the same (eg: both with “int x; int y” in your example), pointers can be passed to functions with either struct type. You can use this to add fields (eg: int z) to structures, and extend a 2d vector into a 3d one… With a bit of creative thought, and const…

You can also put function pointers in a struct, which is sometimes useful. The syntax is ugly, but you can do a lot of OO stuff that way too.

Re: Everything I wish I knew when learning C

#76
The couple of times I tried to really learn C I ran into the same problems. I started by trying to answer two questions: what are the modern features of C that I need to learn to use it, and what style/rules should I follow.

What I found is a body of several C spec updates that are each defined in reference to previous C spec updates. So I'm supposed to... ? Learn C from the 70s and then study each version update and mentally diff everything to figure out what C is now?

Then in terms of rules and style, unlike when K&R C was published, I couldn't find any authority. Actually what I see is that even programmers who have been writing C for many years frequently debate what practices are correct vs not. You can see it in this very thread. Every language has this, but I've seen it much more with C than other languages.

Actually learning the material for me is hard when I can't even get a firm handle on what it is I'm supposed to learn.

Re: Everything I wish I knew when learning C

#77
post #35
post #6

Some constructive feedback: > Here are the absolute essential flags you may need. I highly recommend including `-fsanitize=address,undefined` in there (docs: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.h... ). (Edit: But probably not in release builds, as @rmind points out.) > The closest thing to a convention I know of is that some people name types like my_type_t since many standard C types are like…

How can a (badly chosen) typedef name trigger _undefined behavior_, and not just, say, a compilation error...? I find it difficult to imagine what that would even mean.

One potential issue would be that the compiler is free to assume any type with the name `foobar_t` is _the_ `foobar_t` from the standard (if one is added), it doesn't matter where that definition comes from. It may then make incorrect assumptions or optimizations based on specific logic about that type which end up breaking your code.

Re: Everything I wish I knew when learning C

#78
post #7

This looks decent, but I'm (highly) opposed to recommending `strncpy()` as a fix for `strcpy()` lacking bounds-checking. That's not what it's for, it's weird and should be considered as obosolete as `gets()` in my opinion. If available, it's much better to do the `snprintf()` way as I mentioned in a comment last week, i.e. replace `strcpy(dest, src)` with `snprintf(dst, sizeof dst, "%s", src)` and always remember tha…

Ah, that was one of my less considered additions - thank you for the feedback!

Re: Everything I wish I knew when learning C

#79
post #74

> Everything I wish I knew when learning C By far my biggest regret is that the learning materials I was exposed to (web pages, textbooks, lectures, professors, etc.) did not mention or emphasize how insidious undefined behavior is. Two of the worst C and C++ debugging experiences I had followed this template: Some coworker asked me why their function was crashing, I edit their function and it sometimes crashes or do…

Was rewriting the stack due to undefined behavior or was it due to a logic error, e.g. improper bounds calculation?

Re: Everything I wish I knew when learning C

#80
post #6

Some constructive feedback: > Here are the absolute essential flags you may need. I highly recommend including `-fsanitize=address,undefined` in there (docs: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.h... ). (Edit: But probably not in release builds, as @rmind points out.) > The closest thing to a convention I know of is that some people name types like my_type_t since many standard C types are like…

Why the hell "potentially reserved" was introduced? How is it different from simply "reserved" in practice except for the fact such things can be missing? How do you even use a "potentially reserved" entity reliably? Write your own implementation for platforms where such an entity is not provided, and then conditionally not link it on the platforms where it actually is provided? Is the latter even possible?

Also, apparently, "function names [...] beginning with 'is' or 'to' followed by a lowercase letter" are reserved if and/or are included. So apparently I can't have a function named "touch_page()" or "issue_command()" in my code. Just lovely.

Post reply on HN