6 ms·
What I often find myself lacking in C is a way to overload functions only on pointer constness. Consider elem *array_get(array *a, int idx) If I only have a
by colonwqbang 5y ago
What I often find myself lacking in C is a way to overload functions only on pointer constness. Consider
elem *array_get(array *a, int idx)
If I only have a const pointer to a, I cannot use this function. I have to add a second getter for const usecase, or use casting which seems unsafe.
I would like array_get to return a const pointer if the input was a const pointer, and a full pointer otherwise.
Macros can do this. But it would be nice if it worked for functions as well.
- deleted 5y ago[deleted]
- nly 5y agoWell, you can slowly turn C in to C++... or you can just use a subset of C++. As a C++ fan, and to play devils advocate, the argument against CV-qualifier overloading is that it often results in code duplication. I.e. the implementation of both array_get's would be syntactically identical. In modern C++ you can avoid this by making "array*" a template parameter (T*), and let the compile deduce the return type for the function (use auto) from what you actually return. Many C++ haters don't get that a lot of C++ features build on others.
- nuerow 5y ago> Well, you can slowly turn C in to C++... or you can just use a subset of C++. Those two are not the same. It requires far more expertise and experience to be able to strong-arm C++ into generating lean C-like code than just writing C and getting what you want right out of the box.
- nly 5y ago> It requires far more expertise and experience to be able to strong-arm C++ into generating lean C-like code than just writing C and getting what you want right out of the box. Even if that were true, and I protest that it isn't (I feel it's easier to generate good code in C++ than C), adding individual C++ features to C will just erode that ability to reason.
- RicardoLuis0 5y agohave you considered using C11's _Generic feature? It allows you to maunally implement function overloading: https://godbolt.org/z/jxjvnMTPT https://godbolt.org/z/jxjvnMTPT
- zabzonk 5y ago> I would like array_get to return a const pointer if the input was a const pointer, and a full pointer otherwise Pointers (and other types) don't have "const-ness" attached to them - it's entirely dependent on the declaration of the function. Also, in C++ you can't overload on function return types.
- jstimpfle 5y agoMy advice is to not bother using const much. It's quirky since data that is "const" for one part of the code might not be for another. But no one has figured out a way to represent such a constness-transition. You can find this issue with APIs like "strstr()" for example. And IIRC Dennis Ritchie himself raised these concerns when const was conceived. The deeper issue I think is that const should be an attribute of the _code_ (as in, "I won't modify this data"), not of the data. Data is rarely truly constant (RAM cells are obviously writeable). I use "const" mostly in "const char *" (for string-literals which are pointers to "reasonably const" memory, i.e. read-only mapped memory), and sometimes for function parameters to indicate that the function does not write through the pointer, but as in "strstr()" example this quickly gets quirky. Note that for this simple example you can work around if you take a const-pointer and return an index instead. Summary: Be practical, don't overthink it.
- pantalaimon 5y ago> Data in general is never const On MCUs const data (along with the whole .text section) is stored in flash which is very much const. That's also why you want to use const whenever possible so you are not wasting precious RAM.
- jstimpfle 5y agoAlready changed that to "is rarely truly constant". Also, that flash can be written, even if not during the lifetime of a process. > That's also why you want to use const whenever possible so you are not wasting precious RAM. My point is to not overthink placement of "const" in function parameters, local variables, etc. Because those don't make any difference to the compiled output. I already mentioned string literals as one type of "reasonably constant" data, and of course any other thing that goes in the .rodata section (such as globally declared const variables) is as much constant. To wrap it up, the "const" keyword totally makes sense in global declarations to make them go to .rodata. Using const for type-checking purposes can get quirky on the other hand.
- sgtnoodle 5y agoMost MCUs can mutate their flash, though, and most large embedded projects have one or two weird features that depend on mutating flash and then accessing it as const data. Also, Harvard architectures like AVR have different address spaces for flash vs. ram, so const variables still end up copied into RAM unless you qualify the variable types with non-standard decorators. Being able to explicitly tell the compiler, "you can and should compile this out" seems like a good thing?
- saurik 5y agoI mean, in C you can't overload functions on anything, including even the number of arguments... is this really the most interesting thing to want to overload? I'll claim the C way to do this is to just give yourself an array_get_const.