Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Wrap your structs in a typedef

NOOoooooo, please stop doing this. unless you are a library author who gets to define things like uint8_t, please do not do this

> Use struct wrappers for strong typing

even BIGGER no. This is completely misunderstanding what a typedef is and what it should be used for.



I think you don't understand why typedef is used for structs in C and what do struct wrappers have to do with typedefs? It seems to me you don't understand what is being said here.


Could you please share why wrapping structs in a typedef is bad? I'm culpable of doing this quite often.


There is nothing wrong with either practice. The GP is just stating their preferred style.

In fact it is good practice to use struct wrappers for void* pointers to get type safety. On the other hand, a typedef is just for programmer convenience and the compiler doesn't care.

Eg: See DECLARE_HANDLE defined under STRICT at https://renenyffenegger.ch/notes/Windows/development/WinAPI/...


It is largely considered bad and misleading style. Why would you ever hide that a variable is a srruct? Better to keep typedef only for basic types and for function pointers.


Why would I ever care if something is a struct or not a struct? Just that is almost zero useful information.

I do care about the size of a struct sometimes, but that would require me to go to the definition of the struct, so just seeing the word "struct" didn't help me one bit.

And I of course care about the members of the struct, but that again requires me to know what the actual members are which the word "struct" doesn't give me.

So what exactly does omitting the word "struct" hide again?


How is it hidden? Can't the inquiring mind simply examine the codebase to see it's a struct? And if they choose not to, isn't it on them if it turns out to be something other than what they assumed it was without looking?


I think so. Even with a compiled library distributed with a header file but no source, the header file needs to forward declare something like 'typedef struct foo FOO;' So (unless there's some clever trick I've missed) you can always tell it's a struct but not necessarily see the definition.

There is a point, perhaps a little specious, that you put a module's data structures behind a typedef so the interface doesn't change if it changes from a simple data type to a struct. Probably doesn't happen too often.

The perfect C object-oriented-style interface is FILE* from stdio.h. A FILE is a structure full of operating-system-specific file information but you never have to see it or worry about what's in it, you just use the functions.


> There is a point, perhaps a little specious, that you put a module's data structures behind a typedef so the interface doesn't change if it changes from a simple data type to a struct. Probably doesn't happen too often.

you could never do this in C. If it is a "value type" i.e. a non-pointer, then you cannot change the size of the value, without changing the ABI and the function decl.


It is hidden because you have to "examine" somewhere else before you know. But it doesn't matter, because you don't need to know unless it is subject to invisible implicit conversions. What might you do differently, having "examined" the typedef?


I understand the preference for keeping the struct tag, but virtually no other language does this, with modern IDEs it's trivial to find out what the definition of a given type is, so the tag seems superfluous to me in practice.


We don't even need modern IDEs. ctags solved this problem last century.


The only bad or misleading typedef is one that conceals that a type is a pointer or reference, and therefore implicitly converts to another type.

Technically, int32_t is bad in that way, but we are not fooled by it.


> Technically, int32_t is bad in that way, but we are not fooled by it.

Meaning? On my system int32_t is directly typedefed to unsigned int, absolutely no hidden pointers or conversions.


int32_t promotes to long, converts to unsigned, and truncates to short and char, all silently.


The struct tag is an idea that's survived into approximately zero other languages. It's largely visual clutter.


It is common practice and IMO not bad at all.


It's not necessarily bad, but personally I hardly ever do it, and at work the style guide says no. Gets annoying for other readers to keep checking what something really is, and even for the writer it's usually just extra toil that won't really help you.

Like, my variable is already declared as `int meters` probably. I don't need the redundancy of saying `meters_t meters`. Maybe I even want to store meters as a `long` in certain contexts.


>even BIGGER no. This is completely misunderstanding what a typedef is and what it should be used for.

Hard disagree.

Life safer when dealing with things like SI unit types. I used to use lots of suffixes - _km, _m, _seconds, _hours, but I found that to be a lot more noisy (especially derived units and Nth order stuff like acceleration, seconds_per_second, etc) and evidently it would sneak in errors when you started doing calculations and passing them to functions.

Definitely want different types when I have these three representations flowing around in the program:

pressure_bits_t - raw data from the sensor, gets filtered/averaged in this form, then converted to one of these at various stages:

pressure_pascal_x10_t - integer pascal * 10 (i.e fixed point, one decimal)

pressure_millibar_t - floating point in millibar


_t is even a "reserved" suffix in C. Stop using it. If you want compile-time type safety, pick another language like Haskell. A "typedef" is by no means a contract declaration in C.


No it is not reserved, it's just posix's personal style guides. There's just as much of a name clash possibility when not using _t because lots of other libraries and platforms uses some other convention.

Only ISO C can reserve things, no one else, and ISO C does not reserve the _t suffix.


I think it is pedantic to say that POSIX's guidance is not the de-facto C standard, or at least that the union of rules between ISO and POSIX




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: