473,385 Members | 2,044 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

"memset" vs "= {0}"...Are they equivalent if your initializing variables?

Say you have a struct:

struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};

and you want to declare an instance of that struct and initialize it
to zero. Is "memset" necessary or can i simply initially set it equal
to {0}.

Is this:
MYSTRUCT myStruct = {0};

the same as this:
MYSTRUCT myStruct;
memset(&myStruct, 0, sizeof(MYSTRUCT));

?

The first way seems faster, but I see alot of people doing it the
second way. Could someone please shed some light on the subject?
TIA.
Jul 22 '05 #1
17 19765

<No****@runtime.com> wrote in message
news:fq********************************@4ax.com...
Say you have a struct:

struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};

and you want to declare an instance of that struct and initialize it
to zero. Is "memset" necessary or can i simply initially set it equal
to {0}.

Is this:
MYSTRUCT myStruct = {0};

the same as this:
MYSTRUCT myStruct;
memset(&myStruct, 0, sizeof(MYSTRUCT));

?

The first way seems faster,
Why do you say it 'seems faster'? The only way to tell if it is faster is to
time it (or if you are very knowledgable look at the generated machine
code). Remeber compilers are usually pretty code at optimising code, I would
certainly hope that the two methods would be exactly the same on a good
compiler (but I haven't actually checked this).
but I see alot of people doing it the
second way. Could someone please shed some light on the subject?
The two ways are the same for the struct you have declared. But if you had a
struct with members that had a constructor (e.g. a std::string) then memset
would be wrong. So that is the advantage of the second method, it works in
more situations and you could reasonable hope to get a compiler error
message if you used it incorrectly.
TIA.


john
Jul 22 '05 #2
On Wed, 22 Sep 2004 03:17:47 -0500, No****@runtime.com wrote:
Say you have a struct:

struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};

and you want to declare an instance of that struct and initialize it
to zero. Is "memset" necessary or can i simply initially set it equal
to {0}.

Is this:
MYSTRUCT myStruct = {0};

the same as this:
MYSTRUCT myStruct;
memset(&myStruct, 0, sizeof(MYSTRUCT));

?

The first way seems faster, but I see alot of people doing it the
second way. Could someone please shed some light on the subject?


The first way is generally better, since it zero initializes all
members. Memsetting to 0 is not always the same as zero initializing,
particularly for floating point and pointer members, which may have 0
values that aren't all bits zero.

Performance wise, I don't know which would be faster, you'd have to
measure it.

Tom
Jul 22 '05 #3
> would be wrong. So that is the advantage of the second method, it works in

I meant first method.

john
Jul 22 '05 #4
> struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};
MYSTRUCT myStruct = {0};
All this does is set "myStruct.x" to 0, all the others
still contain no particular value.

MYSTRUCT myStruct;
memset(&myStruct, 0, sizeof(MYSTRUCT));


This is the Microsoft way of doing things.

In fact, they've even made a... uh... macro... out of it
called "ZeroMemory" which you use like so:

ZeroMemory(&myStruct, sizeof(MYSTRUCT));

Don't use the Microsoft way. It's non-portable, plus it
screws things up when you have the likes of:

struct Blah
{
int k;
std::string p;
};

Instead, do the following:

struct Blah
{
int x;
int y;
int w;
int h;
std::string r;
};

Blah poo = Blah();

This gives all member variables their default value, which
for the intrinsic types is 0, for pointer is the null
pointer value which may or may not be represented by 0
(memset is unaware of this and as such can screw things
up), and for classes it calls their default constructor
with no arguments.
Blah poo = Blah();

is superiour in every way and is fully portable. Use it!
-JKop
Jul 22 '05 #5

"JKop" <NU**@NULL.NULL> wrote in message news:1Z*******************@news.indigo.ie...
All this does is set "myStruct.x" to 0, all the others
still contain no particular value.
Wrong answer....When you omit terms in an aggregate initializer the rest
are default initialized.

Instead, do the following:

struct Blah
{
int x;
int y;
int w;
int h;
std::string r;
};

Blah poo = Blah();

So would
Blah poo = { 0 };

Jul 22 '05 #6
On Wed, 22 Sep 2004 11:02:21 GMT, JKop <NU**@NULL.NULL> wrote:
struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};

MYSTRUCT myStruct = {0};


All this does is set "myStruct.x" to 0, all the others
still contain no particular value.


Nope, remaining members are value-initialized, which for built-ins
means initialized to 0. You can also do:

MYSTRUCT myStruct = {};

to get the same effect.

Tom
Jul 22 '05 #7
> MYSTRUCT myStruct = {};
Cool! Didn't know that.

The only advantage

MYSTRUCT myStruct = MYSTRUCT();

would have over it thought is that it can be used for *any*
type, as opposed to just for arrays and POD's. My proposal
would be especially preferable for use in a template.

-JKop
Jul 22 '05 #8
On Wed, 22 Sep 2004 11:02:21 GMT, JKop <NU**@NULL.NULL> wrote:
struct Blah
{
int x;
int y;
int w;
int h;
std::string r;
};

Blah poo = Blah();

This gives all member variables their default value, which
for the intrinsic types is 0, for pointer is the null
pointer value which may or may not be represented by 0
(memset is unaware of this and as such can screw things
up), and for classes it calls their default constructor
with no arguments.
Blah poo = Blah();

is superiour in every way and is fully portable. Use it!
-JKop


Not necessarily. Of the three methods I've tested, Blah()
appears to be the slowest.

The method:

Blah poo;
memset(&poo, 0, sizeof(Blah));

is the fastest, and

Blah poo = {0}

is a very close second;

Basically, you must compromise speed for safety and portability.

This is first time I've ever timed functions. I'm Visual Studio.NET
2003, SDK, WindowsXP.

My timing algorithm:
LARGE_INTEGER start;
LARGE_INTEGER end;
QueryPerformanceCounter( &start );
....Do Something
QueryPerformanceCounter( &end );
TRACE( TEXT( "Time = %d\n" ), end.QuadPart-start.QuadPart );

Granted, we're talking minimal differences, but that's besides the
point.

Please explain a little deeper as to why memset might not set a
pointer or a floating point number to zero. It does on my computer.

-Nollie
Jul 22 '05 #9
> Not necessarily. Of the three methods I've tested, Blah()
appears to be the slowest.

The method:

Blah poo;
memset(&poo, 0, sizeof(Blah));

is the fastest, and

Blah poo = {0}

is a very close second;

Basically, you must compromise speed for safety and portability.

This is first time I've ever timed functions. I'm Visual Studio.NET
2003, SDK, WindowsXP.

My timing algorithm:
LARGE_INTEGER start;
LARGE_INTEGER end;
QueryPerformanceCounter( &start );
...Do Something
QueryPerformanceCounter( &end );
TRACE( TEXT( "Time = %d\n" ), end.QuadPart-start.QuadPart );

Granted, we're talking minimal differences, but that's besides the
point.

Please explain a little deeper as to why memset might not set a
pointer or a floating point number to zero. It does on my computer.

-Nollie


Sometimes it takes me 10mins 23secs to get to the bustop. Sometimes it takes
9mins 58secs...

I wouldn't use "QueryPerformanceCounter" as an indicator for this, unless
you time it a few thousand times and get the average, but even still, I'm
not sure how accurate it'd be.

As regards pointers... well let's say that on a certain system, a pointer
variable takes up 32 bits in memory, as so:
0000 0000 0000 0000 0000 0000 0000 0000
What you're looking at above is "all bits zero". On Windows, this indicates
that the pointer is a null pointer. Now imagine a system where the memory
address 0 is a valid one, ie. it's the first byte of memory, and that on
this particular system, the null pointer value is:

1111 1111 1111 1111 1111 1111 1111 1111
When you write a program with the following line in it:
int* p_k = 0;

The compiler doesn't produce code that sets all bits to zero... no no...
what it does is produce code that sets it to the null pointer value for that
system (and/or for that type, I believe systems may choose to have different
null pointer values depending on the type...). But "memset" doesn't have a
clue about this, all it does is set all bits to zero, which may be a valid
memory address on some systems, hence it's not portable.

And as regards floating point numbers, implementations aren't obligated to
represent the value zero as "all bits zero" either.

I don't see how either of the three could be slower/faster than each other,
they should all yield the same machine code (except maybe the call to
"memeset" might add overhead if it's not inline...)
-JKop
Jul 22 '05 #10
JKop posted:
Not necessarily. Of the three methods I've tested, Blah () appears to be the slowest.

The method:

Blah poo;
memset(&poo, 0, sizeof(Blah));

is the fastest, and

Blah poo = {0}

is a very close second;

Basically, you must compromise speed for safety and portability.
This is first time I've ever timed functions. I'm Visual Studio.NET 2003, SDK, WindowsXP.

My timing algorithm:
LARGE_INTEGER start;
LARGE_INTEGER end;
QueryPerformanceCounter( &start );
...Do Something
QueryPerformanceCounter( &end );
TRACE( TEXT( "Time = %d\n" ), end.QuadPart- start.QuadPart );
Granted, we're talking minimal differences, but that's besides the point.

Please explain a little deeper as to why memset might not set a pointer or a floating point number to zero. It does on my computer.
-Nollie
Sometimes it takes me 10mins 23secs to get to the bustop.

Sometimes it takes 9mins 58secs...

I wouldn't use "QueryPerformanceCounter" as an indicator for this, unless you time it a few thousand times and get the average, but even still, I'm not sure how accurate it'd be.

As regards pointers... well let's say that on a certain system, a pointer variable takes up 32 bits in memory, as so:
0000 0000 0000 0000 0000 0000 0000 0000
What you're looking at above is "all bits zero". On Windows, this indicates that the pointer is a null pointer. Now imagine a system where the memory address 0 is a valid one, ie. it's the first byte of memory, and that on this particular system, the null pointer value is:
1111 1111 1111 1111 1111 1111 1111 1111
When you write a program with the following line in it:
int* p_k = 0;

The compiler doesn't produce code that sets all bits to zero... no no... what it does is produce code that sets it to the null pointer value for that system (and/or for that type, I believe systems may choose to have different null pointer values depending on the type...). But "memset" doesn't have a clue about this, all it does is set all bits to zero, which may be a valid memory address on some systems, hence it's not portable.

And as regards floating point numbers, implementations aren't obligated to represent the value zero as "all bits zero" either.

I don't see how either of the three could be slower/faster than each other, they should all yield the same machine code (except maybe the call to "memeset" might add overhead if it's not inline...)

-JKop


And I hope you realize what havoc "memset" would cause with
a non-POD type...

-JKop
Jul 22 '05 #11
"JKop" <NU**@NULL.NULL> wrote in message
news:1Z*******************@news.indigo.ie...
struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};

MYSTRUCT myStruct = {0};


All this does is set "myStruct.x" to 0, all the others
still contain no particular value.


I think not. If you brace-initialize any elements of an aggregate, the ones
you don't mention get set to zero.

So, for example:

int x[5] = { 42 };

and

int x[5] = { 42, 0, 0, 0, 0 };

are equivalent.
Jul 22 '05 #12
One thing I forgot to mention:

When you do "memset", padding bits (if any) get altered
too. I'm not sure if the Standard allows this...
-JKop
Jul 22 '05 #13

"JKop" <NU**@NULL.NULL> wrote in message news:OY*******************@news.indigo.ie...
One thing I forgot to mention:

When you do "memset", padding bits (if any) get altered
too. I'm not sure if the Standard allows this...

Allows what? You are allowed to access them, yes their state
is undefined during normal assignment/initialization.

Jul 22 '05 #14
Ron Natalie posted:

"JKop" <NU**@NULL.NULL> wrote in message
news:OY*******************@news.indigo.ie...
One thing I forgot to mention:

When you do "memset", padding bits (if any) get altered
too. I'm not sure if the Standard allows this...
Allows what? You are allowed to access them, yes their

state is undefined during normal assignment/initialization.


I'm not sure if the Standard allows you to access the
padding bits.

For instance, if you have:

struct Blah
{
int a;
char b;
char c;
char d;
int b;
};
Chances are that it will be lain out in memory as so:

| a | b | c | padding | d
You can access the object as follows:

poo.a
poo.b
poo.c
poo.d

And a copy constructor and a assignment operator will both
copy the four member variables, but I'm not sure if the
Standard gives us control over the padding bits... anyone
know? I recall looking in the Standard for this before and
finding nothing.

Let's say hypothetically speaking that you *can't* mess
with padding bits. A certain implementation, when you do
the following:

Blah poo;
char x;

Might stick "x" into memory as so:

| a | b | c | x | d |
Again, I stress *hypothetically speaking*.

So does anyone know if the Standard allows messing with
padding?
-JKop


-JKop
Jul 22 '05 #15

"JKop" <NU**@NULL.NULL> wrote in message news:YP*******************@news.indigo.ie...

I'm not sure if the Standard allows you to access the
padding bits.
Read the last paragraph of 3.10 of the standard.
And a copy constructor and a assignment operator will both
copy the four member variables, but I'm not sure if the
Standard gives us control over the padding bits... anyone
know? I recall looking in the Standard for this before and
finding nothing.
The standard doesn't specify any behavior as to what happens to the
pad bytes in assignment or construction.
So does anyone know if the Standard allows messing with
padding?

If you mean aliasing it to char* and then accessing the chars, it is allowed.
Jul 22 '05 #16
>> I'm not sure if the Standard allows you to access the padding bits.

Read the last paragraph of 3.10 of the standard.


<QUOTE>
15 If a program attempts to access the stored value of an object through an
lvalue of other than one of the following
types the behavior is undefined48):
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic
type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified
version of the dynamic type of
the object,
— an aggregate or union type that includes one of the aforementioned types
among its members (including,
recursively, a member of a subaggregate or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic
type of the object,
— a char or unsigned char type.
</QUOTE>
Hmmm... I suppose.
Anyone?
-JKop
Jul 22 '05 #17
In article <66********************************@4ax.com>,
<No****@runtime.com> wrote:
Please explain a little deeper as to why memset might not set a
pointer or a floating point number to zero. It does on my computer.


Because all bits zero is not a valid representation for
floating points or pointers on many platforms.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Jul 22 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: J. Campbell | last post by:
From reading this forum, it is my understanding that C++ doesn't require the compiler to keep code that does not manifest itself in any way to the user. For example, in the following: { for(int...
8
by: Chul Min Kim | last post by:
Hi, I got a BUS ERROR from one of my company's program. Let me briefly tell our environment. Machine : Sun E3500 (Ultra Sparc II 400Mhz CPU 4EA) OS : Solaris7 Compiler : Sun Workshop...
7
by: adelfino | last post by:
I mean: unsigned char foo = ""; is the same as: unsigned char foo; memset (foo, '\0', bar); ?
77
by: M.B | last post by:
Guys, Need some of your opinion on an oft beaten track We have an option of using "goto" in C language, but most testbooks (even K&R) advice against use of it. My personal experience was that...
10
by: steingold | last post by:
Hi all, I wrote an application that takes snapshots using the snapshot monitor API (db2gGetSnapshot and db2GetSnapshotSize), every now and then these methods fail and I get SQL1024N error (A...
13
by: bwaichu | last post by:
Now, I read the faq, and it suggests using sprintf. However, I want to all ways know where the integer finishes in the string. Basically, I want to: nbr | other data But the other data all...
26
by: Frederick Gotham | last post by:
I have a general idea of the different kinds of behaviour described by the C Standard, such as: (1) Well-defined behaviour: int a = 2, b = 3; int c = a + b; (Jist: The code will work...
84
by: aarklon | last post by:
Hi all, I found an interesting article here:- http://en.wikipedia.org/wiki/Criticism_of_the_C_programming_language well what do you guys think of this article....??? Is it constructive...
3
by: Hank | last post by:
Steve Holden wrote: Hi, Steve, This not simply a pathological condition. My people are keeping trying many ways to have job done, and the memory problem became the focus we are paying attention...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.