Thread overview
Floating point values in structs.
Dec 18, 2020
Dave P.
Dec 18, 2020
Adam D. Ruppe
Dec 18, 2020
Dave P.
Dec 22, 2020
Dukc
Dec 22, 2020
Dave P.
December 18, 2020
I got burned by behavior of struct initialization I didn’t anticipate last night.

Consider a struct:

struct Foo {
    float x, y, z;
    int a, b, c;
}

My source C code was initializing it by doing something like:

Foo f = {.y = 3}

Which uses the C behavior that all the other fields will be set to 0.

I thought that the D translation would be:

Foo f = {y: 3}

But to my surprise, that leaves x and z “default initialized”, which means nan!

I have some large structs that are essentially configuration settings for certain subsystems. Is the proper solution to change the struct definition to:

struct Foo {
    float x=0, y=0, z=0;
    int a, b, c;
}

to get the behavior I want?

I find the setting floats to nan pretty bizarre. If the compiler is going to introduce the overhead of initializing all the variables anyway, why set it to nan when integer types get set to the useful default of 0? And if it knows that I am not initializing my floats, why not tell me?
December 18, 2020
On Friday, 18 December 2020 at 16:18:12 UTC, Dave P. wrote:
> Is the proper solution to change the struct definition to:

yeah that's the best option right now

> I find the setting floats to nan pretty bizarre.

yeah i wrote about it here not long ago http://dpldocs.info/this-week-in-d/Blog.Posted_2020_11_23.html#looking-back


excerpt:

"See, the idea behind D's initialization is it catches uninitialized values at runtime. Null pointers crash. NaN floats give NaN results. \ff chars give invalid strings.

The problem is it sets the initializer for int (and friends) to be 0. Which is actually pretty useful and convenient, so people rely on it. Now making uninitialized things an error is infeasible and the fact is it sets a habit to expect 0."

so i think it should be changed. but floats and chars are all weird initialized so be aware of it
December 18, 2020
On Friday, 18 December 2020 at 16:23:20 UTC, Adam D. Ruppe wrote:
> On Friday, 18 December 2020 at 16:18:12 UTC, Dave P. wrote:
>> Is the proper solution to change the struct definition to:
>
> yeah that's the best option right now

A bit of a pain when porting, but alright.

>
>> I find the setting floats to nan pretty bizarre.
>
> yeah i wrote about it here not long ago http://dpldocs.info/this-week-in-d/Blog.Posted_2020_11_23.html#looking-back
>
> [...]

I agree.

Thanks!
December 22, 2020
On Friday, 18 December 2020 at 16:18:12 UTC, Dave P. wrote:
> If the compiler is going to introduce the overhead of initializing all the variables anyway, why set it to nan when integer types get set to the useful default of 0?

Consider default value of `int*`. It is `null`, not a pointer to a newly-allocated 0. Most would probably agree that `null` works better, because it stands for "empty". 0 may or may not, depending on context.

It's this philosophy with floating-point values also. `0.0` might seem like a value when no value is intended, with `nan` there are no ambiguities.

More about this:
https://digitalmars.com/articles/b81.html
https://dlang.org/blog/2018/10/17/interfacing-d-with-c-arrays-part-1/


December 22, 2020
On Tuesday, 22 December 2020 at 18:10:22 UTC, Dukc wrote:
> On Friday, 18 December 2020 at 16:18:12 UTC, Dave P. wrote:
>> [...]

Honestly, I just want all bits zero. I don’t work with any platforms where null is not 0 and all-zero-bits aggregates can be efficiently represented in static storage. I don’t want the compiler inserting a ton of stores of nan to my float members. If I wanted something other than all bits zero for unmentioned members I would write constructors instead of using the struct initializer syntax. I generally design my data types such that all bits zero is a fully valid struct.

But it is what it is. I just have to remember to write `=0` whenever I have a float member or a char member.