zeroing an array

R

richard

From a recent thread, I believe

TYPE *ptr[NUMBER_OF_POINTERS] = {0};

sets every element of the array of pointers to 0. Is

TYPE xyz[NUMBER_OF_ELEMENTS] = {0};

guaranteed to set every element of the arry to 0?

TYPE means any valid type
 
G

Greg P.

| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.

I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

For example:

char array[5];
memset(array, 0, sizeof(array) / sizeof(array[0]));
 
T

Tim Prince

Greg said:
| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.
Static and auto arrays are initialized at different points, so the effect
changes, in a way which might not always jump out at you. In another
language, a change in the standard was instituted late in the game, which
makes initializers force static allocation.
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

For example:

char array[5];
memset(array, 0, sizeof(array) / sizeof(array[0]));
This always struck me as a risky way to go, simply in hope of getting
better performance. Would it work for a data type where sizeof(array[0])
!= 0 ?
 
S

Severian

| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.

Please do name it so others may avoid this broken implementation.
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

For example:

char array[5];
memset(array, 0, sizeof(array) / sizeof(array[0]));

Works only for chars, since sizeof(char) == 1.

Using this for a type whose size is 2 chars will only zero half of
them.

For any array type, you could instead use:

memset(array, 0, sizeof array);

(But why clutter up the code in the first place?)

- Sev
 
T

Tom Zych

Greg P. said:
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

memset() will set every byte to 0x00. I don't think this is
necessarily reliable even if TYPE is an integer type (though it's
usually safe). I wouldn't use it for floating-point types or
pointers.

I presume TYPE is some kind of numeric type, else "setting to zero"
isn't too meaningful.
 
?

=?ISO-8859-1?Q?Johan_Aur=E9r?=

Greg P. said:
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

memset() will set every byte to 0x00. I don't think this is
necessarily reliable even if TYPE is an integer type (though it's
usually safe). I wouldn't use it for floating-point types or
pointers.

As long as you stick to character types it is perfectly legal to use
memset() like this (in both C89 and C99).
 
R

richard

Greg P. said:
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

memset() will set every byte to 0x00. I don't think this is
necessarily reliable even if TYPE is an integer type (though it's
usually safe). I wouldn't use it for floating-point types or
pointers.

I presume TYPE is some kind of numeric type, else "setting to zero"
isn't too meaningful.

TYPE could be anything, such as

typedef struct {
char *this;
int that
struct other xyz[100]
} Example;

In this case, would

Example abc = {0};

set xyz[5] = {0}; ?

More broadly, is

TYPE whatever = {0};

the same as

memset(&whatever, 0, sizeof(whatever));
 
J

Jeff

Greg P. said:
| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.

I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

For example:

char array[5];
memset(array, 0, sizeof(array) / sizeof(array[0]));

In my implementation, I always use xyx[NUMBER] = {0} and it work.

From the standard 6.7.8 (Initialization) 21

........................
21
If there are fewer initializers in a brace-enclosed list than there are
elements or members
of an aggregate, or fewer characters in a string literal used to initialize
an array of known
size than there are elements in the array, the remainder of the aggregate
shall be
initialized implicitly the same as objects that have static storage
duration.

.........................

It said that if we don't put the value in { } for some elements, it will be
initialized as "static storage duration", that means it will be zero. (from
the standard 6.7.8 (10) )

If we write something like " int xyz[100] = {0}", since we didn't list all
the elements except the first one ( xyz[0] ), these elements will be
initialized to 0. That means the whole array is containing 0.

Grep, what is your implementation ? please tell us....

-
Jeff
 
I

Ivan Vecerina

| TYPE could be anything, such as
|
| typedef struct {
| char *this;
| int that
| struct other xyz[100]
| } Example;
|
| In this case, would
|
| Example abc = {0};
|
| set xyz[5] = {0}; ?
Yes.

| More broadly, is
|
| TYPE whatever = {0};
|
| the same as
|
| memset(&whatever, 0, sizeof(whatever));

On most platforms, yes.
In fact, = {0} is more reliable & portable than memset
according to the standard.

Referring to your example above, memset will not guarantee
that the value of the 'this' member is NULL.
Some platform may internally implement NULL as a value
different than zero (although comparison to and assignment
of the 0 value constant to a pointer will behave as expected).

In this case, ={0} will work, but memset will fail.



hth,
 
?

=?ISO-8859-1?Q?Johan_Aur=E9r?=

typedef struct {
char *this;
int that
struct other xyz[100]
} Example;

In this case, would

Example abc = {0};

set xyz[5] = {0}; ?

Yes (although there seems to be a shortage of semicolons up there).
More broadly, is

TYPE whatever = {0};

the same as

memset(&whatever, 0, sizeof(whatever));

No, not in general (though the end result is the same on most platforms).

TYPE whatever = {0};

ensures that pointers are initialized to null pointers, etc. The memset()
call will just clear the bits.
 
A

Al Bowers

Greg said:
| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.

I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

The Standard says:

If there are fewer initializers in a brace-enclosed list than there
are elements or members of an aggregate, or fewer characters in a
string literal used to initialize an array of knownsize than there
are elements in the array, the remainder of the aggregate shall
be initialized implicitly the same as objects that have static storage
duration.

And for static storage:

If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned)
zero;
— if it is an aggregate, every member is initialized (recursively)
according to these rules;
— if it is a union, the first named member is initialized (recursively)
according to these rules.

Therefore;
typedef int TYPE;
TYPE *ptr[NUMBER_OF_POINTERS] = {NULL};

will initialize each element in the array as a null pointer.

------------------and--------------

TYPE value[NUMBER_OF_INTS] = {0};

will initialize each element in the array as a (positive or unsigned)
zero.
 
B

Ben Pfaff

Tim Prince said:
Greg said:
| From a recent thread, I believe
|
| TYPE *ptr[NUMBER_OF_POINTERS] = {0};
|
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type

I had always thought so as I learned this trick from an old programmer.
Unfortunately, on one of my favorite implementations (won't name it), it
doesn't work as expected.
Static and auto arrays are initialized at different points, so the effect
changes, in a way which might not always jump out at you. In another
language, a change in the standard was instituted late in the game, which
makes initializers force static allocation.

Excuse me? The presence of an initializer never affects the
storage duration of an object.
 
T

Tom Zych

Johan said:
As long as you stick to character types it is perfectly legal to use
memset() like this (in both C89 and C99).

Oh, so that is in the standard. Good. Thanks.
 
M

Mark McIntyre

From a recent thread, I believe

TYPE *ptr[NUMBER_OF_POINTERS] = {0};

sets every element of the array of pointers to 0. Is

TYPE xyz[NUMBER_OF_ELEMENTS] = {0};

guaranteed to set every element of the arry to 0?

TYPE means any valid type

this will set the first element of xyz to zero, or the appropriate
value in the relevant type, and the rest to zero, a null pointer or
some appropriate zero-type value.

IF your implementation behaves differently, its broken. Do not however
make the mistake of expecting zero to be a meaningful initialisation
value for some types.
 
J

Jack Klein

Greg P. said:
| sets every element of the array of pointers to 0. Is
|
| TYPE xyz[NUMBER_OF_ELEMENTS] = {0};
|
| guaranteed to set every element of the arry to 0?
|
| TYPE means any valid type
I suggest using memset() and passing 0 as val. It is from string.h. It's
signature is:
void *memset(void *buf, int val, size_t count);

memset() will set every byte to 0x00. I don't think this is
necessarily reliable even if TYPE is an integer type (though it's
usually safe). I wouldn't use it for floating-point types or
pointers.

As long as you stick to character types it is perfectly legal to use
memset() like this (in both C89 and C99).

It is also legal in C99 to use this on an array of any integral type
of a specific bit size, i.e., int16_t, uint_32t, defined in
<stdint.h>, although it is not directly stated in the standard.

You must work it out from several different bits of the standard.

From 7.18.1.1 Exact-width integer types:

<quote>
The typedef name intN_t designates a signed integer type with width N,
no padding bits, and a two’s complement representation. Thus, int8_t
denotes a signed integer type with a width of exactly 8 bits.

The typedef name uintN_t designates an unsigned integer type with
width N. Thus, uint24_t denotes an unsigned integer type with a width
of exactly 24 bits.
<end quote>

Since there are no sign bits an any unsigned int type, all that there
can be are value and padding bits. Since the exact width types
specifically have no padding, every bit in the unsigned form is a
value bit and all bits 0 in any exact width unsigned type must be the
one and only representation of the value 0 for that type.

Next, from 6.2.6.2 on the representation of the integer types:

"For signed integer types, the bits of the object representation shall
be divided into three groups: value bits, padding bits, and the sign
bit. There need not be any padding bits; there shall be exactly one
sign bit. Each bit that is a value bit shall have the same value as
the same bit in the object representation of the corresponding
unsigned type"

So all bits 0 must be a valid representation of the value 0 in any
exact-width signed integer type as well.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
P

Peter Nilsson

Mark McIntyre said:
TYPE xyz[NUMBER_OF_ELEMENTS] = {0};

guaranteed to set every element of the arry to 0?

...Do not however make the mistake of expecting zero to be a meaningful
initialisation value for some types.

For which types is {0} *not* a meaningful initialiser?

Richard Heathfield even initialises va_list-s with it! ;)
 
J

Joona I Palaste

They've just been shipped, we expect them Tuesday.

So are you also a Star Trek fan?

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"Normal is what everyone else is, and you're not."
- Dr. Tolian Soran
 
J

Joona I Palaste

Um, somewhat, but I don't get your reference.

"Generations". Admiral Kirk talking to that guy who is currently captain
of the USS Enterprise. "Don't tell me - Tuesday".

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"'It can be easily shown that' means 'I saw a proof of this once (which I didn't
understand) which I can no longer remember'."
- A maths teacher
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top