Skip to content
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

remove @ptrCast. add @elemCast #1106

Open
andrewrk opened this issue Jun 13, 2018 · 10 comments
Open

remove @ptrCast. add @elemCast #1106

andrewrk opened this issue Jun 13, 2018 · 10 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

Right now, @ptrCast can change the pointer element, but it gives a compile error if you try to change the alignment or const-ness. We already have @alignCast to change the alignment only. Really, this cast is only meant to change the underlying element. So let's make that explicit by having the built-in function only accept the child element type as a parameter, and then it's obvious that the other pointer attributes are unmodified.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jun 13, 2018
@andrewrk andrewrk added this to the 0.4.0 milestone Jun 13, 2018
@andrewrk andrewrk changed the title remove @ptrCast. add @ptrElemCast remove @ptrCast. add @elemCast Jun 13, 2018
@alexnask
Copy link
Contributor

I will work on this one if you don't mind.

@Hejsil
Copy link
Contributor

Hejsil commented Jun 15, 2018

How would we handle:

  • *T -> [*]T -> *T
  • *T -> fn(...) ... -> *T
  • fn(...) ... -> fn(...) ...

@alexnask
Copy link
Contributor

alexnask commented Jun 15, 2018

*T -> [*]T currently does not work even with explicit casting, *T -> *[1]T -> [*]T is required.
The rest do not explicitly cast either.

I'm leaving this up here and will update with further work, will close if the proposal is significantly changed/not approved.

@Hejsil
Copy link
Contributor

Hejsil commented Jun 15, 2018

@alexnask What? I mean the use-cases that the current @ptrCast does just fine:

fn q() void {}

test "" {
    const a: u8 = 0;
    const b = &a;
    const c = @ptrCast([*]const u8, b);
    const d = @ptrCast(*const u8, c);

    // This should work, but I think I hit some compiler bug
    //zig: zig/src/codegen.cpp:5338: LLVMOpaqueValue* gen_const_val(CodeGen*, ConstExprValue*, const char*): Assertion `const_val->data.x_ptr.special == ConstPtrSpecialFunction' failed.
    //[1]    6043 abort (core dumped)  zig test test.zig
    //const e = @ptrCast(fn()u8, b);

    // This should also work...
    //Stored value type does not match pointer operand type!
    //  store void ()* @q, i8 ()** %f, align 8, !dbg !647
    // i8 ()*LLVM ERROR: Broken module found, compilation aborted!
    //const f = @ptrCast(fn()u8, q);
}

@alexnask
Copy link
Contributor

@Hejsil

Right, I was saying those cases do not work without @ptrCast, since you can't "just" cast from one of those types to another, I'm not disagreeing :)

@andrewrk
Copy link
Member Author

How would we handle:

  • *T -> [*]T -> *T

To get from *T to [*]T I propose a userland solution, that does *T -> *[1]T -> [*]T (these are all implicit casts)

To get from [*]T to *T, do this: &foo[0]

  • *T -> fn(...) ... -> *T
  • fn(...) ... -> fn(...) ...

maybe @fnCast? but it wouldn't do fn(...) ... -> *T.

@Hejsil
Copy link
Contributor

Hejsil commented Jun 15, 2018

I guess that could be @intToPtr(*T, @ptrToInt(func)). I think fn -> *T is really rare, while *T -> fn is more "common".

Edit: Wait no. If you got a *T which is a function, then somewhere, a function was casted to *T.

@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Sep 28, 2018
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 May 9, 2019
@Hejsil
Copy link
Contributor

Hejsil commented Jun 5, 2019

Discarding attributes is a very unsafe operations. You can easily discard attributes you don't want to discard with @ptrCast when you refactor code. It's to powerful. That is probably why @ptrCast actually can't discard all pointer attributes (like const).

@elemCast (or just change @ptrCasts behavior but not it's name) is a safer more controlled function. When you really want to do your unsafe operations, you always have the @ptrToInt @intToPtr pair. They can do everything.

@andrewrk
Copy link
Member Author

andrewrk commented Jul 6, 2023

Re-opening for reconsideration in light of two new developments:

@andrewrk andrewrk reopened this Jul 6, 2023
@andrewrk andrewrk modified the milestones: 0.7.0, 0.12.0 Jul 6, 2023
@kocsis1david
Copy link

When you really want to do your unsafe operations, you always have the @ptrToInt @intToPtr pair. They can do everything.

It would be nice if you didn't need two casts for that.

@andrewrk andrewrk modified the milestones: 0.14.0, 0.15.0 Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants