ziglang / zig

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

slightly stricter casting rules for C pointers #2057

Open andrewrk opened 5 years ago

andrewrk commented 5 years ago

IRC user gamester pointed out this example:

const std = @import("std");

fn foo(b: [*c]i32) void {
    std.debug.warn("Value: {}\n", b.*);
}

pub fn main() void {
    var a: i32 = 40;
    foo(&a); // compiles, runs
    foo(a); // compiles, segfaults
}

I created an equivalent C code example:

#include <inttypes.h>
#include <stdio.h>

static void foo(int32_t *b) {
    printf("Value: %d\n", *b);
}

int main() {
    int32_t a = 40;
    foo(a);
    return 0;
}

This actually does compile in C (and has the same runtime behavior), but with clang it gives a warning:

andy@xps ~/tmp> zig build-exe --c-source test.c --library c
test.c:10:9: warning: incompatible integer to pointer conversion passing
      'int32_t' (aka 'int') to parameter of type 'int32_t *' (aka 'int *'); take
      the address with & [-Wint-conversion]
    foo(a);
        ^
        &
test.c:4:26: note: passing argument to parameter 'b' here
static void foo(int32_t *b) {
                         ^

Given that this warning is on by default, I think it would be OK to make this into a compile error. So - definitely an integer other than usize should have an error. Potentially even implicit cast to/from usize could be a problem if the address wasn't comptime known to be zero.

Rocknest commented 5 years ago

Why even cast integer to c-pointer exists? If its used to create null pointers why not use null?

andrewrk commented 5 years ago

null would work once #1967 is implemented. Auto-translated C code will tests such as ptr == 0 which should continue to work. So comptime known 0 would still be an exception even if this proposal is accepted.

Rocknest commented 5 years ago

@andrewrk Is it possible to auto-translate C ptr != 0 ptr != NULL ptr != (void*)0 as ptr != null?

andrewrk commented 5 years ago

@Rocknest yes, and that change is now in master branch: https://github.com/ziglang/zig/commit/e3542196c0b0121fb52d9af599b549cf490e47a8