31 comments

[ 3.7 ms ] story [ 54.4 ms ] thread
I clear structs using a template; saves copying and screwing up the length:

template <class C> SPL_INLINE_FORCE void Zero(C &c) { memset(&c, 0, sizeof(c)); }

struct tm tm_struct;

Zero(tm_struct);

There's also a way to do this without any user-defined functions that works in both C and C++:

    struct tm tm_struct = { 0, };
In ISO C++ and GNU C you can also omit the 0:

    struct tm tm_struct = { };
Does that work on char array members in the struct?
In C, using: struct tm tm_struct = { 0 } ;, the rest of the struct including padding is initialized to zero bits.
Yes, as far as I believe, this should always work in standard C89/C99. In the char array case, it works due to the brace elision rule in aggregates: assuming

    struct foo { char bar[3]; };
These declarations are equivalent:

    struct foo f1 = { 0, };
    struct foo f2 = { { 0, } };
At least in C your initialization functions are first class citizens. Not like in that messed-up language, in which a constructor just should not fail...
What do you mean by "a constructor just should not fail?" Constructors can and do fail in C++.
Of course, in C you'd just use designated initializers and avoid the problem entirely (any unspecified fields are zero-initialized).
Bad correlation.

This is about a bad language that force GOOD developers to figth against it.

"Always use memset onto struct variable before usage, because by default it's filled with garbage."

See? The language PUT GARBAGE on your code. Good or bad developer, not matter.

Now, a more experienced developer will remember that it need to correct the problems the language force on ALL the users.

Not all the blame is in the people. Somethings, the tools are at fault, too..

The language just gave you a block of memory. It lets you decide whether you'd like to dedicate resources to clearing that memory.
Ok, so for what is usefull to have garbage after get memory?
Why do I need to zero an image array if I am about render something into it? You spend time setting each byte to zero.
That, and when your constructor is going to initialize every field, and when you're going to clone a copy of another structure...
I understand if I get null/empty... but garbage?

And in relation to this post, the behaviour is not the same across compilers/archs? Thats nuts.

Welcome to programming in the real world. If that's the nuttiest thing you have to deal with on any given day, it's a good day.
Yep, I know programing is hard. +18 years of it.

Is crazy the amount of punishment a developer accept, and when the fail is elsewhere, it blame itself ;)

No, the compiler avoids unecessary work unless you ask it to.
So, when is necesary to let the garbage without clean it? For what is usefull?

    struct Foo foo;
    foo_init(&foo, bar, baz, quux);
If the language made the first line zero-initialize foo, we'd write the whole of the structure twice; it would be zero-initialized just to be overwritten by foo_init. For many cases, this minor inefficiency would not be a concern. For some uses it would be a major problem.

If you do need to zero-initialize foo, you can do that easily:

    struct Foo foo = { 0 };
"major problem"? Like when?

Sorry to ask this. I have lived outside the C madness this 18 years (pascal and other more saner stuff..), except now using obj-c/js and is crazy the amount of small weird stuff it have..

This make my ask: From where it get the garbage?

Memory returned to the heap. It's recycled, right?
Ah! I get it. Some If the program have 100 "cells" of memory, the first time it get blank, the second what was there before?

Clear the data is costly in the long run? I have read yesterday about data oriented design and it make me understand that now is costly to access memory.

That's exactly it. If you're going to dump data into that memory that is guaranteed to overwrite whatever is already there, then there's no point in wasting cycles zeroing it first.
>See? The language PUT GARBAGE on your code.

It didn't put it there. It just allocated some memory. Not more, not less. If you, for example, malloc a large chunk of memory but don't intend to use it sequentially or not right away, you can save time by not memset'ing it to zero, which would be pointless. C gives you the liberty to defer the initialization, but if you're careless, you'll shoot yourself in the foot. It's very much like having a car with manual vs. automatic transmission. More power = more responsibility. If you need power, you have to accept some compromises, and in this case, the compromise is that you need to mind what's in your memory all the time.

And designated initializers will eventually creep into C++.
Yes, it's possible to make mistakes in C. News at 11. Some mistakes are unique to C, some are shared with C++, and a bloody huge heap of them are unique to C++. What is proven by picking one bug from the first or second bucket and ignoring the third?
> If you wrote your own struct in C++, you have to define constructor to initialize all members with some default values.

No you don't. You are free to define a constructor that leaves some fields as garbage; in fact that's the default behavior.

As long as we're purging evil legacy, this particular bug could also be solved by getting rid of daylight savings time and updating the struct accordingly.
I don't get it?

He didn't initialize a struct properly, results in errors...

Conclusion: C is evil?

I'm sure Bjarne Stroustrup (and the C++ committee) had enough time and resource to mandate that structures are zero-initialized, if they were so inclined. (I mean, think about it: any time you read from an uninitialized value is an undefined behavior, so no conforming program will be broken by this change. Literally.)

The fact that they didn't tells me that this was a conscious decision, not some "Legacy C" cruft that's left there for the sake of backward compatibility. And indeed the core tenet of C++ is "You only pay for what you use", isn't it? Zero-initializing a struct would be against C++'s philosophy.