re-setting an array

S

Scott Kelley

Is there a way to reset all elements of an array with a single instruction?
I want to set all elements to zero. Currently looping to do so.

thx,
Scott Kelley
 
P

Patrik Stellmann

Is there a way to reset all elements of an array with a single instruction?
I want to set all elements to zero. Currently looping to do so.
setting to zero could be done with
void *memset(void *dest, int c, size_t count);

the code could look like:
memset(intArray, 0, sizeof(int) * arraySize);

Very fast but you have to take care of the correct byte-count to be set
to zero yourself!
 
J

John Harrison

Scott Kelley said:
Is there a way to reset all elements of an array with a single instruction?
I want to set all elements to zero. Currently looping to do so.

If you are talking about integers then memset.

If you are talking about floating point then std::fill or std::fill_n. The
advantage of std::fill and std::fill_n is that they work with many
different types, values and data structures, but for integer arrays set to
zero you aren't going to get any more efficient then memset.

john
 
I

Ioannis Vranos

John said:
If you are talking about integers then memset.

If you are talking about floating point then std::fill or std::fill_n. The
advantage of std::fill and std::fill_n is that they work with many
different types, values and data structures, but for integer arrays set to
zero you aren't going to get any more efficient then memset.



Actually, memset() is for values in the range of unsigned char (it fills
bytes). I had forgotten about the fill() family. fill() seems more
elegant, so if not needed i would suggest the OP to use the fill()
family, and use memset() only when he has to.






Regards,

Ioannis Vranos
 
J

John Harrison

Ioannis Vranos said:
Actually, memset() is for values in the range of unsigned char (it fills
bytes).

True but I have never worked on a platform where integer zero wasn't all
bits zero, so I would happily use memset for integers.

john
 
I

Ioannis Vranos

John said:
True but I have never worked on a platform where integer zero wasn't all
bits zero, so I would happily use memset for integers.



Actually now that you mention it, memset() is only safe to be used in
unsigned char sequences only. std::fill() family is the safe approach
definitely.






Regards,

Ioannis Vranos
 
I

Ioannis Vranos

Ioannis said:
Actually now that you mention it, memset() is only safe to be used in
unsigned char sequences

and to char and signed char sequences under some preconditions

only. std::fill() family is the safe approach
definitely.






Regards,

Ioannis Vranos
 
J

Jack Klein

Actually, memset() is for values in the range of unsigned char (it fills
bytes). I had forgotten about the fill() family. fill() seems more
elegant, so if not needed i would suggest the OP to use the fill()
family, and use memset() only when he has to.

No, this is quite silly, it's one of comp.lang.c's pedantic myths.

Actually it has to work for all the character types, because both C
and C++ guarantee that if a signed and unsigned variant of any integer
type contain a value that is within the range of both, the bitwise
representation must be exactly the same.

So all bits 0 must represent the value 0 in both a signed and unsigned
char, and therefore also in a plain char.

Even beyond that, the C standard committee already has accepted a DR
to require wording in the next revision of the C standard specifically
stating that all bits 0 is a valid representation of the value 0 for
_all_ integer types.

I doubt if the C++ standard, which does not allow padding bits in
signed char where the C standard does, will ever suffer this nonsense
about all bits 0 not being the value 0 in any integer type.

On the other hand, for pointers or floating point types, and of course
for non-POD types, using memset() is not a good idea at all.
 
J

Jack Klein

and to char and signed char sequences under some preconditions

Under no preconditions at all.

From paragraph 3 of 3.9.1 Fundamental types:

"The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the value
representation of each corresponding signed/unsigned type shall be the
same."

If there is an implementation where all bits 0 is not the value 0 in a
char or signed char type, then whatever that implementation is it is
not C or C++.
 
I

Ioannis Vranos

Jack said:
Under no preconditions at all.

From paragraph 3 of 3.9.1 Fundamental types:

"The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the value
representation of each corresponding signed/unsigned type shall be the
same."

If there is an implementation where all bits 0 is not the value 0 in a
char or signed char type, then whatever that implementation is it is
not C or C++.


I was talking about values larger than numeric_limits<signed
char>::max() but within the range of unsigned char.

0 is safe for char/signed char/unsigned char always.






Regards,

Ioannis Vranos
 
I

Ioannis Vranos

Jack said:
No, this is quite silly, it's one of comp.lang.c's pedantic myths.

Actually it has to work for all the character types, because both C
and C++ guarantee that if a signed and unsigned variant of any integer
type contain a value that is within the range of both, the bitwise
representation must be exactly the same.


Yes I agree that for 0 it works for all character types, *regardless* of
the representation (it doesn't matter if 0 is all bit zeros or otherwise).

So all bits 0 must represent the value 0 in both a signed and unsigned
char, and therefore also in a plain char.


Bits don't matter here.


Even beyond that, the C standard committee already has accepted a DR
to require wording in the next revision of the C standard specifically
stating that all bits 0 is a valid representation of the value 0 for
_all_ integer types.



Which is entirely off topic in here (otherwise expressed as who cares?). :)



I doubt if the C++ standard, which does not allow padding bits in
signed char where the C standard does, will ever suffer this nonsense
about all bits 0 not being the value 0 in any integer type.



But this doesn't affect memset() in any way.



On the other hand, for pointers or floating point types, and of course
for non-POD types, using memset() is not a good idea at all


Of course. And for integrals other than char/signed char/unsigned char.
And of course for values larger than numeric_limits<signed char>::max()
it shouldn't be used on signed chars, and for values larger than
numeric_limits<char>::max() it shouldn't be used in chars, and for
values larger than numeric_limits<unsigned char>::max() it shouldn't be
used on unsigned chars.


fill() family is better suitable for all purposes, unless we can't do
otherwise.






Regards,

Ioannis Vranos
 
A

Alf P. Steinbach

* Jack Klein:
Under no preconditions at all.

From paragraph 3 of 3.9.1 Fundamental types:

"The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the value
representation of each corresponding signed/unsigned type shall be the
same."

It is worth noting that the standard defines the term "value
representation" in a para preceding this one.

It doesn't mean the representation of a value in terms of 0's and 1's...

This is a case where possibly the intent of the standard is different
from the actual wording, but anyway, it's not a good idea to use memset
for anything if it can be avoided, since it's dangerous in many ways:
the possibility of 0 not being represented by all bits 0 for some types,
the ease with which incorrect limits can be specified, the possibility
of being applied to what is actually non-contigous storage.

I'd advice the OP to use std::vector instead of raw arrays.

Safely & efficiently clearing a std::vector v is very very easy:

zeroAllElementsIn( v );

where zeroAllElementsIn can be defined as

template< typename T >
void zeroAllElementsIn( std::vector<T>& v )
{
std::size_t const size = v.size();
v.clear();
v.resize( size );
}

or

template< typename T >
void zeroAllElementsIn( std::vector<T>& v )
{
std::fill( v.begin(), v.end(), T() );
}

or whatever, just not memset.
 
I

Ioannis Vranos

Alf said:
This is a case where possibly the intent of the standard is different
from the actual wording, but anyway, it's not a good idea to use memset
for anything if it can be avoided, since it's dangerous in many ways:
the possibility of 0 not being represented by all bits 0 for some types,



memset() has nothing to do with bits but with bytes. It sets them to a
value considering them as unsigned chars. For the value 0 this is safe
for all character types, but not for anything else.






Regards,

Ioannis Vranos
 
O

Old Wolf

John Harrison said:
True but I have never worked on a platform where integer zero wasn't all
bits zero, so I would happily use memset for integers.

value zero is guaranteed to be all-bits-zero for the integral types.
 
A

Alf P. Steinbach

* Ioannis Vranos:
memset() has nothing to do with bits but with bytes.

It's a good idea to understand the bit-level of things; that way you can
understand instead of just follow perhaps flawed cookbook recipes.

It so happens that the Holy Standard partially specifies the bit-level
representation of integers.

And the two implicitly allowed representations for unsigned integers
(direct binary, gray code) both have all bits 0 for the value 0.

This follows from the requirements of the shift operators and the
definition of "value representation" mentioned earlier in this thread.

Amazing, isn't it? ;-)


It sets them to a value considering them as unsigned chars.
Whatever.


For the value 0 this is safe
for all character types, but not for anything else.

That is incorrect.
 
I

Ioannis Vranos

Alf said:
It's a good idea to understand the bit-level of things; that way you can
understand instead of just follow perhaps flawed cookbook recipes.

It so happens that the Holy Standard partially specifies the bit-level
representation of integers.

And the two implicitly allowed representations for unsigned integers
(direct binary, gray code) both have all bits 0 for the value 0.



However there are paddings bits on other integer types.

That is incorrect.


Of course it is correct, writing on (bytes containing) padding bits is
undefined behaviour.






Regards,

Ioannis Vranos
 
A

Alf P. Steinbach

* Ioannis Vranos:
* Alf P. Steinbach:
* Ioannis Vranos:

It's a good idea to understand the bit-level of things; that way you can
understand instead of just follow perhaps flawed cookbook recipes.

It so happens that the Holy Standard partially specifies the bit-level
representation of integers.

And the two implicitly allowed representations for unsigned integers
(direct binary, gray code) both have all bits 0 for the value 0.

However there [can theoretically be] paddings bits on other integer types.

Yes. But with a difference between C and C++. C allows more bits used
as padding on signed types relative to corresponding unsigned, C++ does
not; the C++ requirements boil down to msb being used as sign bit.

Of course it is correct

Uhm, no.

writing on (bytes containing) padding bits is undefined behaviour.

Yes, that is correct, but it's not the same. For one can easily ensure
that there are no padding bits (a simple compile time assertion). And
furthermore there are AFAIK no modern machines that use integer padding
bits accessible to a program, so even the un-safety in unchecked context
is purely an academic one, not one that can be encountered in practice.

Hence it should not enter in any consideration of using memset or not.

I've listed other arguments against memset.
 
I

Ioannis Vranos

Alf said:
Yes. But with a difference between C and C++. C allows more bits used
as padding on signed types relative to corresponding unsigned, C++ does
not; the C++ requirements boil down to msb being used as sign bit.


I did not understand what you are saying. For example, signed int and
unsigned int cannot have padding bits?

Yes, that is correct, but it's not the same. For one can easily ensure
that there are no padding bits (a simple compile time assertion).

?



And
furthermore there are AFAIK no modern machines that use integer padding
bits accessible to a program, so even the un-safety in unchecked context
is purely an academic one, not one that can be encountered in practice.



What do you mean they are not accessible in a program. All objects are
accessible including their padding bits.






Regards,

Ioannis Vranos
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top