~andrewrk/ziglang

3 2

Sentinal-terminated arrays from @cImport

Details
Message ID
<YEpRAzVCqVbmFVRT@gpanders.com>
DKIM signature
missing
Download raw message
Hi all!

I have a small little utility that imports configuration from a C header 
file. Example:

     #define OPTION_FOO "some value"
     #define OPTION_BAR "some other value"

In my zig source file, I import this using

     const config = @cImport(@cInclude("config.h"));

This gives me access to config.OPTION_FOO and config.OPTION_BAR in my 
zig code, which is great! The problem is that the type of 
config.OPTION_FOO is [N+1]u8 (where N is the length of "some value" and 
the +1 comes from the null sentinel) and not [N:0]u8, as I would expect.

In my zig code, I convert this value to a zig slice ([]const u8) using 
std.mem.span(config.OPTION_FOO). This worked correctly on zig 0.6.0, but 
stopped working for me when I upgraded to the newest master version 
earlier today. The problem seems to be that when config.OPTION_FOO has 
type [N+1]u8, std.mem.span does not correctly detect that it is a 
null-terminated string and the resulting slice includes the sentinel 
value, which is obviously wrong.

So my question for you all is two-fold:

1) Is this intended behavior or a regression? Put more generally, should 
string values imported from @cImport have type [N+1]u8 or [N:0]u8?

2) Regardless of the answer to (1), what is the correct way to cast this 
array into a string slice (i.e. []const u8)? As mentioned above, with 
zig 0.6.0 I could simply do std.mem.span(config.OPTION_FOO) and all 
worked, but that no longer works as expected since the span function can 
no longer tell that config.OPTION_FOO is null-terminated.

I hope that all makes sense. Let me know if I can clarify anything.

Thanks,

Greg
Details
Message ID
<c8f2d4fc-1663-48f5-a506-ee87db00ab98@www.fastmail.com>
In-Reply-To
<YEpRAzVCqVbmFVRT@gpanders.com> (view parent)
DKIM signature
pass
Download raw message
Hello.

I just tested this with zig 0.8.0-dev.1445+4fc6f631e (latest master at this time) and I don't need to do any casting, config.OPTION_FOO is coerced to a slice by the compiler like this:

    const slice: []const u8 = config.OPTION_FOO; 

In the generated zig code OPTION_FOO is not defined as an array:

    pub const OPTION_FOO = "some value";

So this is confusing if you're also on master.

On Thu, Mar 11, 2021, at 18:18, Gregory Anders wrote:
> Hi all!
> 
> I have a small little utility that imports configuration from a C header 
> file. Example:
> 
>      #define OPTION_FOO "some value"
>      #define OPTION_BAR "some other value"
> 
> In my zig source file, I import this using
> 
>      const config = @cImport(@cInclude("config.h"));
> 
> This gives me access to config.OPTION_FOO and config.OPTION_BAR in my 
> zig code, which is great! The problem is that the type of 
> config.OPTION_FOO is [N+1]u8 (where N is the length of "some value" and 
> the +1 comes from the null sentinel) and not [N:0]u8, as I would expect.
> 
> In my zig code, I convert this value to a zig slice ([]const u8) using 
> std.mem.span(config.OPTION_FOO). This worked correctly on zig 0.6.0, but 
> stopped working for me when I upgraded to the newest master version 
> earlier today. The problem seems to be that when config.OPTION_FOO has 
> type [N+1]u8, std.mem.span does not correctly detect that it is a 
> null-terminated string and the resulting slice includes the sentinel 
> value, which is obviously wrong.
> 
> So my question for you all is two-fold:
> 
> 1) Is this intended behavior or a regression? Put more generally, should 
> string values imported from @cImport have type [N+1]u8 or [N:0]u8?
> 
> 2) Regardless of the answer to (1), what is the correct way to cast this 
> array into a string slice (i.e. []const u8)? As mentioned above, with 
> zig 0.6.0 I could simply do std.mem.span(config.OPTION_FOO) and all 
> worked, but that no longer works as expected since the span function can 
> no longer tell that config.OPTION_FOO is null-terminated.
> 
> I hope that all makes sense. Let me know if I can clarify anything.
> 
> Thanks,
> 
> Greg
>
Details
Message ID
<YEqdjOBbh2wuXYMz@gpanders.com>
In-Reply-To
<c8f2d4fc-1663-48f5-a506-ee87db00ab98@www.fastmail.com> (view parent)
DKIM signature
missing
Download raw message
On Thu, 11 Mar 2021 23:22:35 +0100, Vincent Rischmann wrote:
>Hello.
>
>I just tested this with zig 0.8.0-dev.1445+4fc6f631e (latest master at this time) and I don't need to do any casting, config.OPTION_FOO is coerced to a slice by the compiler like this:
>
>    const slice: []const u8 = config.OPTION_FOO;
>
>In the generated zig code OPTION_FOO is not defined as an array:
>
>    pub const OPTION_FOO = "some value";
>
>So this is confusing if you're also on master.
>

Hi Vincent.

Thanks for your response. I just realized I made a mistake in my initial 
email. My config.h file does not use #define, but rather

     static const char OPTION_FOO[] = "some value";

I can confirm that when using #define OPTION_FOO everything works as 
expected.

I can switch to using #define for my use case, although my original 
question still stands, though now with a slight amendment/addition: are 
C values of type char[] intended to be imported as type [N+1]u8 instead 
of [N:0]u8 in Zig?

Perhaps I will open an issue on GitHub to get more visibility for this 
question.

Greg
Details
Message ID
<d2480fd3-1de4-481d-8406-483593e94411@www.fastmail.com>
In-Reply-To
<YEqdjOBbh2wuXYMz@gpanders.com> (view parent)
DKIM signature
pass
Download raw message
You're right this seems like a bug, there's no easy way to get the data as a []const u8 without some casting trickery as far as I can see. 

On Thu, Mar 11, 2021, at 23:45, Gregory Anders wrote:
> On Thu, 11 Mar 2021 23:22:35 +0100, Vincent Rischmann wrote:
> >Hello.
> >
> >I just tested this with zig 0.8.0-dev.1445+4fc6f631e (latest master at this time) and I don't need to do any casting, config.OPTION_FOO is coerced to a slice by the compiler like this:
> >
> >    const slice: []const u8 = config.OPTION_FOO;
> >
> >In the generated zig code OPTION_FOO is not defined as an array:
> >
> >    pub const OPTION_FOO = "some value";
> >
> >So this is confusing if you're also on master.
> >
> 
> Hi Vincent.
> 
> Thanks for your response. I just realized I made a mistake in my initial 
> email. My config.h file does not use #define, but rather
> 
>      static const char OPTION_FOO[] = "some value";
> 
> I can confirm that when using #define OPTION_FOO everything works as 
> expected.
> 
> I can switch to using #define for my use case, although my original 
> question still stands, though now with a slight amendment/addition: are 
> C values of type char[] intended to be imported as type [N+1]u8 instead 
> of [N:0]u8 in Zig?
> 
> Perhaps I will open an issue on GitHub to get more visibility for this 
> question.
> 
> Greg
>
Reply to thread Export thread (mbox)