ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.23k stars 2.5k forks source link

protection against footgun of pointer casting a double pointer to a single pointer #1890

Open andrewrk opened 5 years ago

andrewrk commented 5 years ago

Here's a mistake that is too easy to make:

fn entry() *c_void {
    return @ptrCast(*const c_void, &entry);
}

The address-of operator is creating a temporary stack variable to store the address of entry, and then converting the address of that to a *const c_void. The programmer gets a double pointer when they only wanted a single pointer.

One solution would be to disallow @ptrCast from double pointers to single pointers.

Rocknest commented 5 years ago

So it should be @ptrCast(*c_void, entry);? If i remember correctly in C both &entry and entry would mean the same. Perhaps make address-of on function names an error?

justinbalexander commented 5 years ago

I like @Rocknest 's idea. C already works that way and that is the behavior that I would expect had I no prior knowledge. If I can pitch my two cents in.

ghost commented 3 years ago

@andrewrk With #1717, entry and &entry will be distinct, and only &entry will be a pointer. That solves the example. There may still be utility in this though, for the same reason we disallow @bitCast on pointer types.

190n commented 1 month ago

Is this still relevant now that function bodies and function pointers are separate? Currently,

export fn entry() *const anyopaque {
    return @ptrCast(entry);
}

is a compiler error and

export fn entry() *const anyopaque {
    return @ptrCast(&entry);
}

has the intended behavior.