Live data from Hacker News

Everything I wish I knew when learning C

tmewett.com

61–70 of 401 posts

Re: Everything I wish I knew when learning C

#61
post #50

Earlier quoted context omitted.

No, it's correct. The asterisk is a little inconsistent, in that it means two opposite things. In the declaration it means "this is a pointer." However, in an expression , it means "this is the underlying type" and serves to dereference the pointer. int a = 5; int *x; // this is a pointer x = &a; int c = *x; // both c and *x are ints If it were *data, it would be equivalent to *(data + 0), which is equivalent to data…

Thanks. Now I understand why I found pointers difficult. It's the declaration that confused me.

You can read a declaration like `int x` as “`x` is an int”, and hence x is an int pointer.

Re: Everything I wish I knew when learning C

#62

> I get an int* value which has 5 ints allocated at it. Not crazy about this array explanation. Better wording would be: "I get a memory address that points to the first byte of a chunk of memory that is large enough to hold 5 ints and tagged as int" > Essential compiler flags Nitpick, but this is only true if you are on a gcc/clang platform. > If you want to “return” memory from a function, you don’t have to use mal…

> Be familiar with the computer architectures you are working on.

But keep in mind that C is not a portable assembly!

Re: Everything I wish I knew when learning C

#63
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.

I'm not sure, but in general having incompatible definitions for the same name is problematic.

Re: Everything I wish I knew when learning C

#65
I would add to this: 1. Visual Studio debugger is really, really good and you should use it to step through your program (or equivalent IDE based workflow). 2. Learn to compile your code with memory safeguards and use the tooling around them. Specific depends on the platform. On POSIX address sanitizer is good I hear. On Windows you can use the debug CRT and gflags to instrument your binary really well.

Re: Everything I wish I knew when learning C

#66
post #35

Earlier quoted context omitted.

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.

The problem being that to trigger a compile error the compiler would have to know all its reserved type names ahead of time. It is not required to do so, hence undefined behavior. You might get a wrong underlying type under that name.

Doesn’t the compiler need to know all of the types to do the compilation anyway?

Re: Everything I wish I knew when learning C

#68
‘ 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 constructive use of pointer-to-functions, you can do quite a bit of OOP stuff in C.

Re: Everything I wish I knew when learning C

#70
> The sizes of arrays are not known in any useful way to C. When I declare a variable of type int[5] in a function, I don’t get a value of type int[5]; I get an int* value which has 5 ints allocated at it. Since this is just a pointer, the programmer, not the language, has to manage copying the data behind it and keeping it valid.

This is not quite correct. Assuming arrays == pointers is usually true enough, but it isn't actually true. This[1] SO thread has some useful information in it, but the TLDR is that actual arrays are treated differently than pointers. You do get an object of type "int array" rather than "int pointer" when you do int[5].

The compiler does know the size of an array allocated like T a[n]. It does not, however, do any bounds checking for you.

[1] https://stackoverflow.com/questions/4607128/in-c-are-arrays-...

Post reply on HN