Reputation: 19333
A colleague and I were debating the efficiency of certain approaches to zero'ing out a struct
. Let's assume we have a simple struct
like so:
struct {
int iMyInt;
char cMyChar;
double dCoordinates[128];
} s_t;
My approach would be to do this:
s_t myStruct = { 0 };
My colleague advised this approach instead:
s_t myStruct = { };
He noted that my approach initializes a single element, and then the rest of the elements, in a two-part operation, while his approach initializes the entire struct
in a one-part operation that is faster and more efficient.
Is this true, and if so, is it always the case across all compiler optimization levels (ie: does the compiler figure this out and optimize it for me anyways)?
Thank you.
Upvotes: 3
Views: 307
Reputation: 145249
C++11 §8.5.1/7:
“ If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list
And last dash of C++11 §8.5.4/3:
“ Otherwise [i.e. T is not a class, not an aggregate, and not a reference], if the initializer list has no elements, the object is value-initialized.
Value-initialized for a simple type like int
means zero-initialized.
So the formal effect of {0}
, for a type that has 0
value, is the same as the formal effect of {}
.
The standard can however not dictate the Quality of Implementation of a compiler. A compiler might react to what it considers bad words in a file name, and just to spite you generate time consuming dummy code before each function call. Likewise it just might, in theory, treat the two notations differently wrt. code generation, even though they mean the same.
Re your colleague’s idea that
“ He noted that my approach initializes a single element, and then the rest of the elements, in a two-part operation, while his approach initializes the entire struct in a one-part operation that is faster and more efficient.
No, that’s just an incorrect vision of how a compiler might work.
Compilers don’t work that way.
But the empty braces notation has the advantage that it also works with e.g. std::string
and any other type T
where T()
is a valid expression, but T(0)
is not.
I.e. it’s slightly more general.
All this said, note that in C++ it’s not necessary to do the C acrobatics
typedef struct Point_tag
{
int x, y;
} Point;
Instead you can simply do
struct Point
{
int x, y;
};
Upvotes: 1
Reputation: 43662
First of all the code you posted is invalid: you should declare that structure type as follows
struct s_t {
int iMyInt;
char cMyChar;
double dCoordinates[128];
};
That said: in your specific case the two approaches are the same and everything is zeroe'd out. At -O3
and even -O0
for clang there are no differences for a generic test code which uses any of the above members and/or array elements (at -O0
it even calls memset
on the entire structure in both cases).
s_t obj = {0};
movq %rcx, %rdi
movl %eax, %esi
callq memset
s_t obj = {};
movq %rcx, %rdi
movl %eax, %esi
callq memset
Upvotes: 6