4 ms·
Can you "launder" pointers through integers just to do things like drop `const`? It's a very common pattern to have to drop attributes like `const` due to crap
by cryptonector 11mo ago
Can you "launder" pointers through integers just to do things like drop `const`? It's a very common pattern to have to drop attributes like `const` due to crappy APIs: `const foo a = ...; foo b = (foo *)(uintptr_t)a;`
- kragen 11mo agoHopefully Pizlo will correct me if I get this wrong, but I don't think Fil-C's pointer tagging enforces constness, which isn't needed for C in any case. This C code compiles with no warnings and outputs "Howlong\n" with GCC 12.2.0-14 -ansi -pedantic -Wall -Wextra: #include <stdio.h> int main() { const char c[] = "Howling\n"; char *p = (char*)c; p[4] = 'o'; printf("%s", c); return 0; } Somewhat to my surprise, it still compiles successfully with no warnings as C++ (renaming to deconst.cc and compiling with g++). I don't know C++ that well, since I've only been using it for 35 years, which isn't nearly long enough to learn the whole language unless you write a compiler for it. Same results with Debian clang (and clang++) version 14.0.6 with the same options. Of course, if you change c[] to *c, it will segfault. But it still compiles successfully without warnings. Laundering your pointer through an integer is evidently not necessary.
- jibal 11mo agoDid you compile with -Wcast-qual?
- kragen 11mo agoNo, that does give a warning.
- pizlonator 11mo agoFil-C capabilities have a read only bit of this purpose.
- kragen 11mo agoInteresting, so you really can enforce constness on references? Does that mean the above code will crash on Fil-C?
- mbrock 11mo agoI tried it and it doesn't crash when compiled with Fil-C, FYI. But I guess it wouldn't be too hard to implement.
- pizlonator 11mo agoJust using const in C isn’t enough, since C’a const is unsound, so I ignore it. But if you try to write to a readonly global constant then you’ll panic. And there are a handful of ways to allocate readonly data via Fil-C’s APIs.
- jacquesm 11mo ago> Just using const in C isn’t enough, since C’a const is unsound, so I ignore it. And now I have confused faces looking at me why I just laughed out loud.
- einsteinx2 11mo ago> I don't know C++ that well, since I've only been using it for 35 years Ok that got a chuckle out of me haha
- cryptonector 11mo ago> > I don't know C++ that well, since I've only been using it for 35 years, which isn't nearly long enough to learn the whole language unless you write a compiler for it. No one person could write a compiler for it, and even if they could they would forget as much in doing so as they could learn.
- kragen 11mo agoWalter Bright did, although maybe C++ has gotten enough bigger since then that your statement has become true.
- Findecanor 11mo agoAs kragen already posted, you can cast from const-pointer to non-const directly. Not allowing a cast from integer to pointer is the point of having pointers as capabilities in the first place. Central in that idea of capabilities is that you can only narrow privileges, never widen them. An intptr_t would in-effect be a capability narrowed to be used only for hashing and comparison, with the right for reading and writing through it stripped away. BTW, if you would store the uintptr_t then it would lose its notion of being a pointer, and Fil-C's garbage collector would not be able to trace it. The C standard allows casts both ways, but the [u]intptr_t types are optional. However, C on hardware capability architectures' (CHERI, Elbrus, I dunno about AS/400) tend to make the type available anyway because the one-way cast is so common in real-world code.
- pizlonator 11mo agoYes. That works. If the laundering through integers is syntactically obvious - obvious that the cast back from int used a int that obviously can from a pointer - then I allow it.
- 1718627440 11mo agoWhat do you need that for, why wouldn't `const foo * a = ...; foo * b = (foo *)a;` work?