3 ms·
I'm not a C developer, so I have to ask: why in the world would you not use const?
by rewgs 3y ago
I'm not a C developer, so I have to ask: why in the world would you not use const?
- jstimpfle 3y agoIt's more work. Not only to put all the annotations correctly, but only because it causes some real headaches. It's easy (implicit) to transition from non-const to const 1 pointer level deep. But the other way around -- it's really awkward to "remove" a const. The strstr() signature is probably the shortest example / explanation why. To implement strstr(), you have to hack the const away to create the return value. Alternatively, create a mutable_strstr() variant that does the exact same thing. This is the kind of boilerplate that we don't want in C (and that C is bad at generating automatically). Think about it this way: Real const data doesn't exist. It always gets created (written) somewhere, and usually removed later. One way where this works cleanly is where the data is created at compile time, so the data can be "truly" const, and be put in .ro section, and automatically destroyed when the process terminates. But often, we have situations where some part of the code needs to mutate the data that is only consumed as read only by other parts of the code. One man's const data is another man's mutable data. In C, the support for making this transition work fluently is just very limited (but I think it's not great in most other languages, either).
- mmoll 3y ago> Real const data doesn't exist Ever seen a ROM? And the C library‘s hacks around not being able to overload functions (which is the only reason for strstr et al‘s weird signature) wouldn‘t stop me from using const. It can be really useful both for documentation and for correctness. Think memcpy, not strstr.
- jstimpfle 3y ago> Ever seen a ROM? How does the data get onto the ROM? But read 2 sentences further, where I had addressed this already. > Think memcpy, not strstr. See my other comments, I do think that making const function parameters is generally good for documentation and compatibility. strstr() is only a showcase for the limitations. Typically, const works for function parameters but not data structures.
- gwd 3y ago> The strstr() signature is probably the shortest example / explanation why. To implement strstr(), you have to hack the const away to create the return value. It seems to me the "hacking" is exactly the side-effect that is wanted. It's like the requirement in Rust to do certain kinds of things in an `unsafe { }` block (or using the `unsafe` package in Go): not that you want the compiler to prevent you from doing things completely, but that you want the compiler to prevent you from doing things by accident. > One man's const data is another man's mutable data. Yes; and the point of `const` for function parameters is to make sure that data isn't mutated unexpectedly.
- jstimpfle 3y ago> It seems to me the "hacking" is exactly the side-effect that is wanted. It is not. It's broken at the surface level. If you passed a pointer that is already const on your side, you get back a non-const pointer back that allows you to write to your const memory.
- deleted 3y ago[deleted]
- P_I_Staker 3y agoYou want to avoid promoting or casting away the const. If you start using const, you almost inevitably wind up with a mismatch. This introduces flaws in the type system. I wish I had a better breakdown on the impact of these concerns, but I'd rather not worry at all. Anyway, if you don't use const, this goes away. Bear in mind the minor amount of "safety" it provides, because you can just ignore it later, as you arguably tend to be doing anyway when you pass a const to non-const or visa versa. Inevitably, outside of really small insular project (and often times even then), there's something down the line that winds up being non-const that you don't want to change. C developers of this mindset tend to just come to the conclusion that you will immediately break the type system, just give up on the whole game. Edit adding at least on example: Example: You define as const and remove the const later. If anything writes to the non-const, this is undefined behavior Example: I believe the above is actually true for const promotion if you modify the non-const version... I think this is only after the call (edit. ie after it become const, really interest in the answer). No Undefined behavior /* I imagine this would be okay */ si_non_const = si_non_const + GetMagicValue(); /* Const is promoted here */ const int fparam = si_non_const; /* Writing to fparam is undefined past here */ f_const(&fparam); Undefined behavior /* I imagine writing, after using as const is also not defined, but is fine at this point */ si_non_const = si_non_const + GetMagicValue(); /* Here we now have a constant value that will never be written to */ const int fparam = si_non_const; f_const(&fparam); /* I think this would also be UB, even though it's accessed through a different symbol */ si_non_const = si_non_const + GetMagicValue(); Interested in other opinion, maybe will think on later... would it be valid for the compiler to remove that last assignment? Edit: Sorry, this is unreadable, if you put a space between the not undefined, and undefined it's easier