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

translate-c: C code that uses string literals as non-const char * #9126

Closed
ehaas opened this issue Jun 15, 2021 · 4 comments · Fixed by #9554
Closed

translate-c: C code that uses string literals as non-const char * #9126

ehaas opened this issue Jun 15, 2021 · 4 comments · Fixed by #9554
Labels
translate-c C to Zig source translation feature (@cImport)
Milestone

Comments

@ehaas
Copy link
Sponsor Contributor

ehaas commented Jun 15, 2021

In C string literals have the type char[N] (not const, but modifying the contents is undefined behavior). C code that uses this isn't compatible with Zig's []const u8 string literals:

int main(void) {
   char *foo = "foo";
   return 0;
}
pub export fn main() c_int {
    var foo: [*c]u8 = "foo";
    return 0;
}
./test.zig:3:23: error: expected type '[*c]u8', found '*const [3:0]u8'
    var foo: [*c]u8 = "foo";
                      ^
./test.zig:3:23: note: cast discards const qualifier
    var foo: [*c]u8 = "foo";

This can occur in variable declarations, function calls, and struct and array initializers - did I miss any?

I noticed in getExprQualType we turn char * into const char * but I'm not sure why or what the implications of removing that are. Another solution would be to detect situations where a string literal is used as a char * and insert intToPtr / ptrToInt to cast away the constness.

@nektro
Copy link
Contributor

nektro commented Jul 14, 2021

(not const, but modifying the contents is undefined behavior)

then what exactly non-const about them?

@ehaas
Copy link
Sponsor Contributor Author

ehaas commented Jul 14, 2021

They're effectively const; It's just that it's a quirk of the C standard that string literals have the type char *, so the technically correct Zig type corresponding to a C string literal would be [N:0]i8 or [N:0]u8 depending on platform char signedness. The other issue is that Zig string literals are const, so the following valid C code can't be translated (since a string literal can't coerce to [*c]u8):

#include <stdlib.h>
char foo(char *s) {
    return s[0];
}
int main(void) {
    if (foo("bar") != 'b') abort();
}

@nektro
Copy link
Contributor

nektro commented Jul 14, 2021

are they able to coerce to a [*c]const u8

@ehaas
Copy link
Sponsor Contributor Author

ehaas commented Jul 14, 2021

Yes, but we can't change the signature of foo since it could theoretically change the string (if it is called with an non-const array or heap-allocated string)

@Vexu Vexu added the translate-c C to Zig source translation feature (@cImport) label Aug 6, 2021
@Vexu Vexu added this to the 0.10.0 milestone Aug 6, 2021
ehaas added a commit to ehaas/zig that referenced this issue Aug 12, 2021
In C the type of string literals is `char *`, so when using them in
a non-const context we have to cast the const away.

Fixes ziglang#9126
ehaas added a commit to ehaas/zig that referenced this issue Aug 14, 2021
In C the type of string literals is `char *`, so when using them in
a non-const context we have to cast the const away.

Fixes ziglang#9126
ehaas added a commit to ehaas/zig that referenced this issue Aug 14, 2021
In C the type of string literals is `char *`, so when using them in
a non-const context we have to cast the const away.

Fixes ziglang#9126
ehaas added a commit to ehaas/zig that referenced this issue Aug 14, 2021
In C the type of string literals is `char *`, so when using them in
a non-const context we have to cast the const away.

Fixes ziglang#9126
Vexu pushed a commit that referenced this issue Aug 21, 2021
In C the type of string literals is `char *`, so when using them in
a non-const context we have to cast the const away.

Fixes #9126
@andrewrk andrewrk modified the milestones: 0.10.0, 0.9.0 Aug 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
translate-c C to Zig source translation feature (@cImport)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants