Live data from Hacker News

Everything I wish I knew when learning C

tmewett.com

51–60 of 401 posts

Re: Everything I wish I knew when learning C

#51
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…

C spec: >That shouldn't be recommended, because names ending with "_t" are reserved. Also C spec naming new things: >_Atomic _Bool I'm glad to see the C folks have a sense of humor.

Not all reserved names are reserved for all purposes. _t is reserved only for type names (typedefs), whereas _Atomic and _Bool are keywords.

Re: Everything I wish I knew when learning C

#53

> 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…

*y in both printf, right?

Re: Everything I wish I knew when learning C

#54

Earlier quoted context omitted.

The way I got this to stick in my head was to always think of * as dereferencing, and tell myself that int *x; is declaring that the type of *x is int.

I like that a lot! However, it makes things like int *x = &a; a bit more confusing/inconsistent.

Not at all!

a is int; &a is pointer to int; x is pointer to int; *x in again int.

Re: Everything I wish I knew when learning C

#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);

Re: Everything I wish I knew when learning C

#56
post #26

> You can cast T to const T, but not vice versa. Humm, actually, you can. But guess what ? Modification of the underlying data is an UB !

Which is the only possible logical consequence of modifying something that others asked you not.

const_cast is there for buggy (or legacy) libraries where const was not specified explicitly, but is implicit in the behavior.

Re: Everything I wish I knew when learning C

#58
post #40

C syntax is already too rich and complex. typedef/enum/(_Generic)/etc should go (fix/cleanup function pointer type declaration). Only sized primitive types (u32/s32,u64/s64,f32/f64 or udw/sdw,uqw/sqw,fdw/fqw...). We would have only 1 loop statement "loop{}", no switch. I am still thinking about "anonymous" code blocks for linear-code variable sub-scoping (should be small compile-unit local function I guess). No integ…

There's a lot in "C", but I don't see anything in it that really isn't needed to serve its modern purpose. In 2022 "C" is used as a portable assembly language. When you really need to control where and how memory is allocated, and represent data structures used directly by the hardware in a high-level language.

> In 2022 "C" is used as a portable assembly language.

No! Only poor programmers use C while reasoning assembly, and then they complain about undefined behaviour.

Re: Everything I wish I knew when learning C

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

But wouldn't one be required to include a particular header in such case (i.e. the correct header for defining a particular type)?

I mean, no typedef names are defined in the global scope without including any headers right? Like I find it really weird that a type ending in _t would be UB if there is no such typedef name declared at all.

Or is this UB stuff merely a way for the ISO C committee to enforce this without having to define ?

Re: Everything I wish I knew when learning C

#60

> 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…

You already know this, but I would add that under strict aliasing rules, this is only valid because x and y point to the same type.

The most common example is when y is float* and someone tries to access its bitwise representation via an int*.

(Please correct me if I'm wrong)

https://gist.github.com/shafik/848ae25ee209f698763cffee272a5...

Post reply on HN