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

> C++ has saner rules for implicit type conversions

I say this partly in jest, but once I have wrapped all my primitives in structs C has a perfectly reasonable rule for implicit type conversions: "don't".



As an embedded firmware developer, I really wish there was a way to outright disallow implicit type conversions in C source code. You'd have to exclude libraries, but I'm creating "typedef enum" to show what I'm doing AND help make sure I don't somehow screw it up. If all of those typedefs are interchangable with each other (and ints and chars), I lose out on part of the functionality.


To get nominal typing in C, wrap things in a struct. There shouldn't be any performance overhead (the generated code should often, if not always, be unchanged), and the boilerplate can be manageable (and you can unpack things locally when it starts to get too messy).

See https://dlthomas.github.io/using-c-types-talk/slides/slides.... (... which I should really turn into a blog post or something)


Some ABIs pass structs containing a single element differently (and in a less performant way) than primitive data types.


You should always be aware of the details of whatever platform you're targeting, to be sure.

That said, can you name a few that work this way? If I've worked on such a platform, it's been a long while.


Apparently ARM64 does this for return values. I remembered the `#[repr(transparent)]` proposal that precisely tackled this problem for Rust: [RFC 1758](https://github.com/rust-lang/rfcs/blob/de0917dca549694fffbe3...).


Thanks, I'll dig in! Is this limited to floating point? That doesn't surprise me nearly as much.


Haha, yes. I've considered similar things before too.

Part of the problem then is that working with any standard library functions is a huge pain. You have to manually "cast" back and forth all the time.


Any library that's not on board needs to be wrapped, for sure. Fortunately you can do it in just the prototypes if you keep things ABI compatible. It fits well with the practice of decorating functions with empty structs, which is always ABI compatible (... in C, with mainstream compilers. In C++ it is explicitly not ABI compatible, sadly).

It's extra important, in writing this kind of C, to pick a granularity of types such that they help you make the distinctions you need without drowning you in casts. And I'm not at all sure such a granularity always exists. It worked out very well on the (greenfield) project I built this way, though.




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

Search: