ziglang / zig

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

zig translate-c fails to translate compound literals like &(float){0.5} #21855

Open Yeaseen opened 1 week ago

Yeaseen commented 1 week ago

Zig Version

0.14.0-dev.2064+b5cafe223

Steps to Reproduce and Observed Behavior

void main() {
    float * p = &(float){0.5};
}

Expected Behavior

translate-c fails to process the compound literal &(float){0.5}, which is a standard C feature allowing in-line temporary variables. Zig translate-c does not generate an equivalent expression in Zig.

The translated Zig code should ideally create a temporary variable for the literal and then assign its address to p.

pub export fn main() void {
    var temp: f32 = @as(f32, @floatCast(0.5));
    _ = &temp;
    var x: [*c]f32 = &temp;
    _ = &x;
}
mlugg commented 1 week ago

translate-c fails to translate and demotes the function to extern:

// test.c:2:25: warning: unsupported initlist type: 'Builtin'

// test.c:1:6: warning: unable to translate function, demoted to extern
pub extern fn foo() void;
rohlem commented 1 week ago

See https://en.cppreference.com/w/c/language/compound_literal for details - note that afaiu the value is not bound the current sub-expression / statement (the closest meaning of "temporary"), but instead to the current scope/block. Even if used in an expression (f.e. a function call), it has to translate to a stack location with lifetime until the end of the current block.

Yeaseen commented 1 week ago

Thank you for the explanation! @rohlem That makes sense regarding the scope and the lifetime of the temporary variable. Just to clarify my main concern, translate-c doesn’t directly translate the compound literal &(float){0.5} in a way that maintains its temporary nature within the current scope or block.

To be more specific, C compound literals like &(float){0.5} create a temporary value with an addressable location that exists until the end of the current block, and it would be ideal if translate-c could mimic this behavior by using a stack-allocated temporary variable. For example, generating something like var temp: f32 = 0.5; in Zig and then assigning p to &temp would produce the expected result and ensure that the temporary exists for the correct scope.