re-setting an array

Discussion in 'C++' started by Scott Kelley, Jul 1, 2004.

  1. Scott Kelley

    Scott Kelley Guest

    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
     
    Scott Kelley, Jul 1, 2004
    #1
    1. Advertising

  2. > 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!
     
    Patrik Stellmann, Jul 1, 2004
    #2
    1. Advertising

  3. Scott Kelley wrote:
    > 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.




    memset() defined in <cstring>.

    Check this: http://www.cplusplus.com/ref/cstring/index.html






    Regards,

    Ioannis Vranos
     
    Ioannis Vranos, Jul 1, 2004
    #3
  4. "Scott Kelley" <> wrote in message
    news:...
    > 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
     
    John Harrison, Jul 1, 2004
    #4
  5. John Harrison wrote:

    > 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
     
    Ioannis Vranos, Jul 1, 2004
    #5
  6. Ioannis Vranos wrote:

    > Scott Kelley wrote:
    >
    >> 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.

    >
    >
    >
    >
    > memset() defined in <cstring>.
    >
    > Check this: http://www.cplusplus.com/ref/cstring/index.html




    As i mentioned in another reply, better use the fill() family instead,
    unless you have to use memset().


    Check this: http://h30097.www3.hp.com/cplus/fill_n_3c__std.htm






    Regards,

    Ioannis Vranos
     
    Ioannis Vranos, Jul 1, 2004
    #6
  7. "Ioannis Vranos" <> wrote in message
    news:cc0ihl$2asq$...
    > John Harrison wrote:
    >
    > > 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).


    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
     
    John Harrison, Jul 1, 2004
    #7
  8. John Harrison wrote:

    >>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.




    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
     
    Ioannis Vranos, Jul 1, 2004
    #8
  9. Ioannis Vranos wrote:

    > 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
     
    Ioannis Vranos, Jul 1, 2004
    #9
  10. Scott Kelley

    Jack Klein Guest

    On Thu, 01 Jul 2004 11:38:25 +0300, Ioannis Vranos
    <> wrote in comp.lang.c++:

    > John Harrison wrote:
    >
    > > 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.


    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.

    --
    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++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 2, 2004
    #10
  11. Scott Kelley

    Jack Klein Guest

    On Thu, 01 Jul 2004 12:24:57 +0300, Ioannis Vranos
    <> wrote in comp.lang.c++:

    > Ioannis Vranos wrote:
    >
    > > 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


    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++.

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

    >
    > Regards,
    >
    > Ioannis Vranos


    --
    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++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 2, 2004
    #11
  12. Jack Klein wrote:

    > 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
     
    Ioannis Vranos, Jul 2, 2004
    #12
  13. Jack Klein wrote:

    > On Thu, 01 Jul 2004 11:38:25 +0300, Ioannis Vranos
    > <> wrote in comp.lang.c++:
    >
    >
    >>John Harrison wrote:
    >>
    >>
    >>>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.

    >
    >
    > 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
     
    Ioannis Vranos, Jul 2, 2004
    #13
  14. * Jack Klein:
    > On Thu, 01 Jul 2004 12:24:57 +0300, Ioannis Vranos
    > <> wrote in comp.lang.c++:
    >
    > > Ioannis Vranos wrote:
    > >
    > > > 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

    >
    > 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.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 2, 2004
    #14
  15. Alf P. Steinbach wrote:

    > 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
     
    Ioannis Vranos, Jul 2, 2004
    #15
  16. Scott Kelley

    Old Wolf Guest

    "John Harrison" <> wrote:
    >
    > 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.
     
    Old Wolf, Jul 2, 2004
    #16
  17. * Ioannis Vranos:
    > Alf P. Steinbach wrote:
    >
    > > 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'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.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 2, 2004
    #17
  18. Alf P. Steinbach wrote:

    >>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.




    However there are paddings bits on other integer types.


    >>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.



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






    Regards,

    Ioannis Vranos
     
    Ioannis Vranos, Jul 2, 2004
    #18
  19. * Ioannis Vranos:
    > * 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.

    >
    > 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.


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

    > >
    > > That is incorrect.

    >
    > 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.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 2, 2004
    #19
  20. Alf P. Steinbach wrote:

    > 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?


    >>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.




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






    Regards,

    Ioannis Vranos
     
    Ioannis Vranos, Jul 2, 2004
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Srinivasa Raghavan Sethuraman
    Replies:
    0
    Views:
    567
    Srinivasa Raghavan Sethuraman
    Jun 30, 2004
  2. CJ
    Replies:
    1
    Views:
    1,585
    Andrew Thompson
    Oct 29, 2004
  3. Sile
    Replies:
    5
    Views:
    705
  4. Replies:
    0
    Views:
    482
  5. Replies:
    2
    Views:
    1,132
Loading...

Share This Page