c2compiler icon indicating copy to clipboard operation
c2compiler copied to clipboard

Compiler: force zero initialization of local variables

Open chqrlie opened this issue 2 months ago • 8 comments

  • make all local variables zero-initialized except if tagged as @(noinit)
  • update tests

chqrlie avatar Oct 18 '25 20:10 chqrlie

The generated C code creates something like this for integers:

int32_t from = { 0 };

I was surprised that this was allowed at all, but I think it would be more readable to just generate

int32_t from = 0;

and only generate braces for structs, etc

I did measure the performance and saw no change

bvdberg avatar Oct 20 '25 08:10 bvdberg

I agree this PR needs polishing to this regard. My goal is for you to test the performance impact. The main issue is probably the initialization of local arrays, especially if they are large. This can be avoided with the @noinit attribute, but I would prefer the analyser to be able to determine that full initialization is unnecessary.

chqrlie avatar Oct 20 '25 08:10 chqrlie

It should easily opt out zero init, already at -O1. This works fine here at least: https://godbolt.org/z/M4sTEr5zv

lerno avatar Oct 20 '25 21:10 lerno

It should easily opt out zero init, already at -O1. This works fine here at least: https://godbolt.org/z/M4sTEr5zv

Redundant initialization seems easy to handle.

How about this one:

module test;
import stdio local;

fn void main() {
    char buf[4096];
    snprintf(buf, sizeof(buf), "Hello world");
    printf("%s\n", buf);
    return 0;
}

chqrlie avatar Oct 20 '25 21:10 chqrlie

That's something that would require @noinit. Note that it would not be correct to elide the implicit zeroing in this case, since the bytes not affected by snprintf will not be modified, and that might be what the programmer intended.

lerno avatar Oct 20 '25 21:10 lerno

That's something that would require @noinit. Note that it would not be correct to elide the implicit zeroing in this case, since the bytes not affected by snprintf will not be modified, and that might be what the programmer intended.

Indeed snprintf does not affect the bytes beyond offset 11, but since printf never reads them, leaving them uninitialized is a palatable optimisation. This is very similar to the case of unused local variables: I suppose C3 does not initialize them either.

chqrlie avatar Oct 20 '25 21:10 chqrlie

It would be an optimization, but none that the compiler can do without inlining the functions. If it did, then the zero init would be removed I'm sure. Unused local variables are zero init:ed but -O1 will just remove them no problem.

lerno avatar Oct 20 '25 21:10 lerno

It would be an optimization, but none that the compiler can do without inlining the functions. If it did, then the zero init would be removed I'm sure. Unused local variables are zero init:ed but -O1 will just remove them no problem.

I agree with this approach and that's what I would like to achieve through static analysis in many cases.

chqrlie avatar Oct 20 '25 21:10 chqrlie