www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - default initialization of char arrays

reply Walter Bright <newshound2 digitalmars.com> writes:
This came up in an email exchange. Consider:

```
import core.stdc.stdio;

__gshared char[10] xxx = [0]; // initialize xxx to all zeros

void main()
{
     foreach (c; xxx)
         printf("%d\n", c);
}
```

A `char` default initializes to 0xFF. The programmer wanted to default 
initialize the array of char to 0, and so used [0] to initialize it. This 
resulted in `[0,255,255,255,255,255,255,255,255,255]`. He asked how to default 
initialize it to 0 without having to tediously enumerate the 0 for each element 
in the initializer.

The answer is:
```
__gshared char[10] xxx = 0;
```
Sep 08
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
https://dlang.org/spec/arrays.html#static-init-static
Sep 08
parent reply Vindex9 <tech.vindex gmail.com> writes:
On Monday, 8 September 2025 at 15:44:27 UTC, Walter Bright wrote:
 https://dlang.org/spec/arrays.html#static-init-static
I've been programming in D for many years because of such wonderful language features. But, in my opinion, we need to focus on stabilizing and fixing what we already have. Speaking of static arrays, I’d like to remind that we've had a long-standing bug with a segmentation fault: type inference doesn't work for a static array of type `real[1]`. ``` void main() { import std.stdio : writeln; real[1] arr = 0; writeln(arr); // SEGFAULT } ``` https://github.com/dlang/dmd/issues/21323
Oct 02
parent Vindex9 <tech.vindex gmail.com> writes:
Correction: array output to screen does not work.
Oct 02
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
You can also use this for default initialization of structs:

```
struct S { int a=1,b=2,c=3; char[10] x = 0; }
```
Sep 08
parent reply pete <email email.com> writes:
On Monday, 8 September 2025 at 15:50:06 UTC, Walter Bright wrote:
 You can also use this for default initialization of structs:

 ```
 struct S { int a=1,b=2,c=3; char[10] x = 0; }
 ```
I didn't notice you could do that. In the past I have used something like this monstrous thing to make a static array of zero-initialised floats :) ``` float[N] list = iota(0, N).map!((int i) => 0).staticArray!(float[N]); ```
Sep 08
parent Walter Bright <newshound2 digitalmars.com> writes:
On 9/8/2025 10:03 AM, pete wrote:
 I didn't notice you could do that.
It seems to be an overlooked feature, which is why I posted it.
Sep 08
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright wrote:
 He asked how to default initialize it to 0 without having to 
 tediously enumerate the 0 for each element in the initializer.
That is not what the email exchange was about. Last DConf you claimed (paraphrased): 'Default initializing chars to 255 (and floats to nan) in D prevents bugs and makes the programmer's intent clearer.' I shared an experience of the opposite, where this C code from Mingw: ```C OSVERSIONINFOEXW vi = {sizeof(vi),0,0,0,0,{0},0,0,0,VER_NT_WORKSTATION}; ``` Got incorrectly translated to this in druntime: ```D OSVERSIONINFOEXW osvi = { OSVERSIONINFOEXW.sizeof, 0, 0, 0, 0, [0], 0, 0, 0, VER_NT_WORKSTATION }; ``` https://github.com/mingw-w64/mingw-w64/blob/849a151baf187f32eb57b34c00365cbc7d2353a7/mingw-w64-headers/include/versionhelpers.h#L82C5-L82C77 https://github.com/dlang/dmd/blob/dd2a35af794efb1eb72864f7aafbcd0f551e75ca/druntime/src/core/sys/windows/winver.d#L259 Before finding the C code, it was unclear to me what the intention was of `[0]`: is it meant to initialize to `[0, 255, 255, ...]` or `[0, 0, 0, ...]`? I turns out it was supposed to be the latter, but because of D's non-zero default initialization the compiler did the former. Either way, cases like this will be prevented in the future by https://github.com/dlang/dmd/pull/21821
Sep 09
prev sibling next sibling parent reply JN <666total wp.pl> writes:
On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright wrote:
 This came up in an email exchange. Consider:

 ```
 import core.stdc.stdio;

 __gshared char[10] xxx = [0]; // initialize xxx to all zeros
I feel like in such scenario a warning should be issued, or even compilation error, "static array initialization expects 10 values, only 1 provided". Sooner or later someone will hit the same issue again and spend hours debugging why the array doesn't get zeroed.
Sep 10
parent reply Ogion <ogion.art gmail.com> writes:
On Wednesday, 10 September 2025 at 23:35:29 UTC, JN wrote:
 I feel like in such scenario a warning should be issued, or 
 even compilation error, "static array initialization expects 10 
 values, only 1 provided". Sooner or later someone will hit the 
 same issue again and spend hours debugging why the array 
 doesn't get zeroed.
Yep, the syntax should be more explicit. Something like this: ```D float[10] x = [42, ...]; // [42, NaN, ..., NaN] float[10] y = [1:42, ...]; // [NaN, 42, NaN, ..., NaN] ```
Oct 01
parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 1 October 2025 at 18:09:27 UTC, Ogion wrote:
 On Wednesday, 10 September 2025 at 23:35:29 UTC, JN wrote:
 I feel like in such scenario a warning should be issued, or 
 even compilation error, "static array initialization expects 
 10 values, only 1 provided". Sooner or later someone will hit 
 the same issue again and spend hours debugging why the array 
 doesn't get zeroed.
Yep, the syntax should be more explicit. Something like this: ```D float[10] x = [42, ...]; // [42, NaN, ..., NaN] float[10] y = [1:42, ...]; // [NaN, 42, NaN, ..., NaN] ```
nah they just going to break it without a replacement
Oct 01
parent reply not you <not you.not> writes:
On Wednesday, 1 October 2025 at 20:00:35 UTC, monkyyy wrote:
 On Wednesday, 1 October 2025 at 18:09:27 UTC, Ogion wrote:
 On Wednesday, 10 September 2025 at 23:35:29 UTC, JN wrote:
 I feel like in such scenario a warning should be issued, or 
 even compilation error, "static array initialization expects 
 10 values, only 1 provided". Sooner or later someone will hit 
 the same issue again and spend hours debugging why the array 
 doesn't get zeroed.
Yep, the syntax should be more explicit. Something like this: ```D float[10] x = [42, ...]; // [42, NaN, ..., NaN] float[10] y = [1:42, ...]; // [NaN, 42, NaN, ..., NaN] ```
nah they just going to break it without a replacement
you can always create a mixin
Oct 01
parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 1 October 2025 at 21:01:28 UTC, not you wrote:
 On Wednesday, 1 October 2025 at 20:00:35 UTC, monkyyy wrote:
 On Wednesday, 1 October 2025 at 18:09:27 UTC, Ogion wrote:
 On Wednesday, 10 September 2025 at 23:35:29 UTC, JN wrote:
 I feel like in such scenario a warning should be issued, or 
 even compilation error, "static array initialization expects 
 10 values, only 1 provided". Sooner or later someone will 
 hit the same issue again and spend hours debugging why the 
 array doesn't get zeroed.
Yep, the syntax should be more explicit. Something like this: ```D float[10] x = [42, ...]; // [42, NaN, ..., NaN] float[10] y = [1:42, ...]; // [NaN, 42, NaN, ..., NaN] ```
nah they just going to break it without a replacement
you can always create a mixin
replacing 1 line of code with 30 isnt great
Oct 01
parent not you <not you.not> writes:
On Wednesday, 1 October 2025 at 21:28:00 UTC, monkyyy wrote:
 On Wednesday, 1 October 2025 at 21:01:28 UTC, not you wrote:
 On Wednesday, 1 October 2025 at 20:00:35 UTC, monkyyy wrote:
 On Wednesday, 1 October 2025 at 18:09:27 UTC, Ogion wrote:
 On Wednesday, 10 September 2025 at 23:35:29 UTC, JN wrote:
 [...]
Yep, the syntax should be more explicit. Something like this: ```D float[10] x = [42, ...]; // [42, NaN, ..., NaN] float[10] y = [1:42, ...]; // [NaN, 42, NaN, ..., NaN] ```
nah they just going to break it without a replacement
you can always create a mixin
replacing 1 line of code with 30 isnt great
how often do you need this 'feature'? can you show a real world usecase?
Oct 01
prev sibling next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright wrote:

 The answer is:
 ```
 __gshared char[10] xxx = 0;
 ```
I've just run into this: ``` enum Type: char[4] { invalid = 0, } ``` Error: cannot implicitly convert expression `0` of type `int` to `char[4]` Should work, I guess.
Sep 30
prev sibling next sibling parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright wrote:
 […]

 A `char` default initializes to `0xFF`. The programmer wanted 
 to default initialize the array of char to `0`, and so used 
 `[0]` to initialize it. This resulted in 
 `[0,255,255,255,255,255,255,255,255,255]`. He asked how to 
 default initialize it to `0` without having to tediously 
 enumerate the `0` for each element in the initializer.
Please make this footgun an error. The compiler can tell you in the error message to use `= x` instead of `= [x]`, since it’s a common pattern in C. My best bet is that no-one uses `[0]` being in fact `[0, 0xFF …]` intentionally.
Oct 15
parent monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 15 October 2025 at 11:51:05 UTC, Quirin Schroll 
wrote:
 On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright 
 wrote:
 […]

 A `char` default initializes to `0xFF`. The programmer wanted 
 to default initialize the array of char to `0`, and so used 
 `[0]` to initialize it. This resulted in 
 `[0,255,255,255,255,255,255,255,255,255]`. He asked how to 
 default initialize it to `0` without having to tediously 
 enumerate the `0` for each element in the initializer.
Please make this footgun an error. The compiler can tell you in the error message to use `= x` instead of `= [x]`, since it’s a common pattern in C. My best bet is that no-one uses `[0]` being in fact `[0, 0xFF …]` intentionally.
Only because of the insane idea of intentionally invalid initialization `int[N]=[1,2,3]` being trailing zeros makes more sense
Oct 15
prev sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Monday, 8 September 2025 at 15:42:27 UTC, Walter Bright wrote:
 This came up in an email exchange. Consider:

 ```
 import core.stdc.stdio;

 __gshared char[10] xxx = [0]; // initialize xxx to all zeros

 void main()
 {
     foreach (c; xxx)
         printf("%d\n", c);
 }
 ```

 A `char` default initializes to 0xFF. The programmer wanted to 
 default initialize the array of char to 0, and so used [0] to 
 initialize it. This resulted in 
 `[0,255,255,255,255,255,255,255,255,255]`. He asked how to 
 default initialize it to 0 without having to tediously 
 enumerate the 0 for each element in the initializer.

 The answer is:
 ```
 __gshared char[10] xxx = 0;
 ```
At least the compiler is smart enough to know that the following is an error. ``` void main() { char[10] xxx = [0]; } ```
Oct 15