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

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;`




Hopefully 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.


> 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


> > 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.


Walter Bright did, although maybe C++ has gotten enough bigger since then that your statement has become true.

Fil-C capabilities have a read only bit of this purpose.

Interesting, so you really can enforce constness on references? Does that mean the above code will crash on Fil-C?

Just 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.


> 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.


I tried it and it doesn't crash when compiled with Fil-C, FYI. But I guess it wouldn't be too hard to implement.

Did you compile with -Wcast-qual?

No, that does give a warning.

As 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.


Yes. 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.


What do you need that for, why wouldn't `const foo * a = ...; foo * b = (foo *)a;` work?



Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: