4 ms·
>A common example of a harmful abstraction, in C and C++, is a typedef of a pointer to an opaque name. The typedef conceals, when you read code using it, that t
by fluoridation 5y ago
>A common example of a harmful abstraction, in C and C++, is a typedef of a pointer to an opaque name. The typedef conceals, when you read code using it, that the type is really a pointer, and so subject to all the excess operations provided for pointers in those languages. But one thing every C and C++ programmer always needs to know about a type they are working with is whether it is a pointer.
Nah, I don't agree at all. Renamed generic pointers are actually an extremely useful signal. They say "you should not concern yourself with what this pointer points to. You should only be using it through the library's functions. Do anything else with it at your own peril". Also, no, C and C++ programmers don't really care whether a value of some novel type is actually a pointer or not (C++ programmers much less so). They only care about what size it is to know how to pass it around and whether it needs to be cleaned up in some specific way. If I tell you that when you're done with a fluor_t you should pass it to release_fluor(), do you need to know whether fluor_t is a pointer or a struct, or whether release_fluor() is a function or a macro?
- ncmncm 5y agoAnywhere it would have been useful to "rename a pointer", it would be more useful to wrap it in a type that defines exactly the operations intended, and none that are not. If users have to call release_fluor(), your abstraction has failed to earn its keep.
- fluoridation 5y agoAre you talking about a C or C++ API? If C++ then yes, I agree that would not be an idiomatic API. If C, then no, that's a perfectly typical API for the language.
- ncmncm 5y agoIf you will need to release it, then you also need to know it is a pointer that would afterward refer to freed storage. Programmers understand that referents of pointers have lifetime that must be managed. Hiding that quality of your special-snowflake type does nobody any good.
- fluoridation 5y ago>If you will need to release it, then you also need to know it is a pointer that would afterward refer to freed storage. You really don't. If the documentation says that after calling release_fluor(), the fluor_t that was passed to it can't be passed to get_fluor_mass(), it doesn't matter whether fluor_t is a pointer or not. I'm sorry, but you're just plainly wrong.
- ncmncm 5y agoIf you are relying on everybody who reads code that uses your type to have thoroughly scoured all the documentation, you are Doing It Wrong. Programmers understand pointers and pointer semantics: when they see a pointer, they know what is required of them. An opaque type that has pointer semantics you can't tell without reading up on documentation is, exactly, an abstraction that costs more than it delivers.
- fluoridation 5y agoOkay. Have fun using C APIs without reading documentation and wondering why your programs keep crashing, I guess. What else can I say?
- ncmncm 5y agoI know why programs other people write keep crashing. They are coding them in C (or bad C++; but I repeat myself), and are relying on abstractions that conceal exactly that which they should instead expose.
- MaxBarraclough 5y ago> If you are relying on everybody who reads code that uses your type to have thoroughly scoured all the documentation, you are Doing It Wrong. As fluoridation indicated, this is the norm in C programming. By means of example, in the OpenCL C library, bitfields all use the same type. You have to consult a function's documentation to know what you're allowed to pass. [0] I do agree that the 'Ada-style' approach to types is far superior to the 'C-style', but Doing It Wrong seems a bit strong, unless you want to condemn all C code. With the right library you can use the 'Ada-style' in C++. Specifically, using a 'strong typedef' library which prevents implicit conversions, such as [1], but not Boost's strong_typedef which permits implicit conversion back to the underlying type. Unfortunately this kind of thing isn't possible in C. > Programmers understand pointers and pointer semantics: when they see a pointer, they know what is required of them Not really. Should you call free on the pointer once you're done with it? The type alone doesn't tell you. You need to consult the documentation to know how you are meant to use the value, whether or not a pointer type is used. [0] https://www.khronos.org/registry/OpenCL/specs/2.2/html/OpenCL_API.html#clCreateCommandQueueWithProperties https://www.khronos.org/registry/OpenCL/specs/2.2/html/OpenC... [1] https://github.com/foonathan/type_safe/ https://github.com/foonathan/type_safe/