Everything I wish I knew when learning C
71–80 of 401 posts
Re: Everything I wish I knew when learning C
#72Additionally 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> 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);
Re: Everything I wish I knew when learning C
#74By 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…
Re: Everything I wish I knew when learning C
#76What 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
#77Some 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.
Re: Everything I wish I knew when learning C
#78This 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…
Re: Everything I wish I knew when learning C
#79> 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…
Re: Everything I wish I knew when learning C
#80Some 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…
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.