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

Zig struggles with linking or translating arrays of c-string #22315

Open
Daimanta opened this issue Dec 25, 2024 · 0 comments
Open

Zig struggles with linking or translating arrays of c-string #22315

Daimanta opened this issue Dec 25, 2024 · 0 comments
Labels
bug Observed behavior contradicts documented or intended behavior translate-c C to Zig source translation feature (@cImport)
Milestone

Comments

@Daimanta
Copy link

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

Consider the following C file

#include <stdio.h>

void case1() {
    char* foo = "bar";
    puts(foo);
}

void case2() {
    char *cat[2] = { "r<=", "r=" };
    puts(cat[0]);
    puts(cat[1]);
}

void case3() {
    char cat[2][4] = { "r<=", "r=" };
    puts(cat[0]);
    puts(cat[1]);
}

int main() {
    case1();
    case2();
    case3();
}

This code is valid C and will produce all the strings listed without issue. The simple case is well supported and is not an issue. It however becomes an issue with both case2 and case3.

Consider the translated code


pub extern fn puts(__s: [*c]const u8) c_int;

pub export fn case1() void {
    var foo: [*c]u8 = @as([*c]u8, @ptrCast(@volatileCast(@constCast("bar"))));
    _ = &foo;
    _ = puts(foo);
}
pub export fn case2() void {
    var cat: [2][*c]u8 = [2][*c]u8{
        "r<=",
        "r=",
    };
    _ = &cat;
    _ = puts(cat[@as(c_uint, @intCast(@as(c_int, 0)))]);
    _ = puts(cat[@as(c_uint, @intCast(@as(c_int, 1)))]);
}
pub export fn case3() void {
    var cat: [2][4]u8 = [2][4]u8{
        "r<=",
        "r=",
    };
    _ = &cat;
    _ = puts(@as([*c]u8, @ptrCast(@alignCast(&cat[@as(c_uint, @intCast(@as(c_int, 0)))]))));
    _ = puts(@as([*c]u8, @ptrCast(@alignCast(&cat[@as(c_uint, @intCast(@as(c_int, 1)))]))));
}

Case1 is again handled correctly with appropriate casts. Case2 and case3 have issues however.

Expected Behavior

Both with linking and translating I would expect case2 and case3 to work as they are valid(perhaps a tad unconventional) c.
I would guess that a number of additional casts is required to make the code work as if it were c.

pub export fn case2() void {
    var cat: [2][*c]u8 = [2][*c]u8{
        @constCast("r<="),
        @constCast("r="),
    };
    _ = &cat;
    _ = puts(cat[@as(c_uint, @intCast(@as(c_int, 0)))]);
    _ = puts(cat[@as(c_uint, @intCast(@as(c_int, 1)))]);
}

These added constCasts seem to work.

Case3 was the original case I encountered, where is the error expected type '[4]u8', found '*const [3:0]u8' pops up. This is harder to solve as it might have arbitrary data after the null-sentinel in the string. I do not know if there are appropriate casts possible here.

When linking the code as c code case 2 gives error: expected type '[[*c]u8', found '*const [3:0]u8](cimport.zig:1151:9: error: expected type '[*c]u8', found '*const [3:0]u8') and case 3 gives cimport.zig:1151:9: error: expected type '[4]u8', found '*const [3:0]u8' which indicate the same problem. As the code is valid c, it should also be accepted and used as is.

@Daimanta Daimanta added the bug Observed behavior contradicts documented or intended behavior label Dec 25, 2024
@Vexu Vexu added the translate-c C to Zig source translation feature (@cImport) label Dec 25, 2024
@Vexu Vexu added this to the 0.15.0 milestone Dec 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior translate-c C to Zig source translation feature (@cImport)
Projects
None yet
Development

No branches or pull requests

2 participants