Skip to content

feat: allow taking pointerof(self) in structs #15903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

BlobCodes
Copy link
Contributor

This MR allows taking pointerof(self) inside a struct instance.
It only works for structs, there's an error message when attempting to take pointerof(self) inside a class or meta-class since it would be hard to define proper behavior for them.

This is already possible by defining a empty ivar at the beginning of the struct, this just makes it simpler and safer:

struct Foo
  # Before
  @beginning = uninitialized UInt8[0]
  def this : self*
    pointerof(@beginning).as(self*)
  end

  # After
  def this : self*
    pointerof(self)
  end
end

I think this MR might be a bit controversial, but since the change was so simple, I thought I'd just create the MR directly.

TODO:

  • Add specs
  • Test with interpreter

@straight-shoota
Copy link
Member

Sounds reasonable.
Still, I think such a change would require some discussion. What is it useful for? Why is this a good solution for that? What are the drawbacks? Alternatives?
This may sound a bit bureaucratic, but I think it would be best to start an RFC about this: https://github.com/crystal-lang/rfcs/
It doesn't need to be big. A very concise description should be fine.
Since this is a language change, it's very useful to have it properly documented.

@ysbaddaden
Copy link
Contributor

ysbaddaden commented Jun 16, 2025

There would be a couple benefit:

  1. the intent would be explicit;

  2. as far as I know we make no guarantee over the order of ivars in objects (be they structs or classes), and only guarantee that order ivars are in the order of definition for extern structs (lib structs or @[Extern]) that only accept a limited set of primitive types.

    When we implement a mechanism to order ivars, to reduce padding for example, taking the pointer of the first defined ivar won't necessarily be the first struct member (unless extern struct), while pointerof(self) would.

Though I'm wondering if self isn't already a pointer type, so instead of taking a pointer to self, we shouldn't just cast it to a pointer (as in references) 🤔

@ysbaddaden
Copy link
Contributor

I thought I had some use cases with structs that are directly mapped in memory but I just replaced them with an empty static array: @payload = uninitialized UInt8[0] then @payload.to_unsafe 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants