| Topic: |
DEVELOP > C |
| User: |
"Gaijinco" |
| Date: |
26 Jan 2008 03:02:39 PM |
| Object: |
memset |
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
Thanks.
.
|
|
| User: "Keith Thompson" |
|
| Title: Re: memset |
26 Jan 2008 04:03:57 PM |
|
|
Gaijinco <gaijinco@gmail.com> writes:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
No, you can be 99% positive that v[i] != 1 for i > 0. (The remaining
1% is for systems with sizeof(int)==1, and therefore CHAR_BIT>=16;
you're unlikely to run into such a system unless you're working with
embedded DSPs.)
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
Right. memset sets each *byte* of an object to a specified value. It
happens that setting each byte of an int to 0 sets the entire int to
0. Setting each byte of an int to 1 will probably set the entire int
to something like 0x0101 (257), or 0x01010101 (16843009), or even
0x0101010101010101 (72340172838076673, if I've done the math right).
The C standard library doesn't provide functions to set each element
of an array to a specified value, other than memset. You'll just have
to write a loop (untested code follows):
int v[1000000];
size_t i;
for (i = 0; i < sizeof v / sizeof v[0]; i ++) {
v[i] = 1;
}
It's likely to be about as fast as memset() would have been anyway.
--
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.
|
|
|
| User: "Eric Sosman" |
|
| Title: Re: memset |
26 Jan 2008 04:21:34 PM |
|
|
Keith Thompson wrote:
Gaijinco <gaijinco@gmail.com> writes:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
No, you can be 99% positive that v[i] != 1 for i > 0. (The remaining
1% is for systems with sizeof(int)==1, and therefore CHAR_BIT>=16;
you're unlikely to run into such a system unless you're working with
embedded DSPs.)
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
Right. memset sets each *byte* of an object to a specified value. It
happens that setting each byte of an int to 0 sets the entire int to
0. Setting each byte of an int to 1 will probably set the entire int
to something like 0x0101 (257), or 0x01010101 (16843009), or even
0x0101010101010101 (72340172838076673, if I've done the math right).
The C standard library doesn't provide functions to set each element
of an array to a specified value, other than memset. You'll just have
to write a loop (untested code follows):
int v[1000000];
size_t i;
for (i = 0; i < sizeof v / sizeof v[0]; i ++) {
v[i] = 1;
}
It's likely to be about as fast as memset() would have been anyway.
For very large arrays that need to be filled/refilled very
many times, here's a function I cooked up long ago:
#include <string.h>
void fillmem(void *pdest, size_t sdest,
const void *pfrom, size_t sfrom)
/*
* Fills the `sdest' bytes starting at `pdest' with copies
* of the `sfrom' bytes starting at `pfrom'. The final copy
* will be partial if `sfrom' does not divide `sdest'.
*/
{
if (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pfrom = pdest;
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
while (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
sfrom += sfrom;
}
}
memcpy (pdest, pfrom, sdest);
}
<off-topic> At first glance and even at second glance, this looks
like a cache-killer. But on the platforms I've tested it doesn't
appear to suffer from cache-aliasing problems. It seems likely
that memcpy() on these platforms is implemented cleverly (and non-
portably) to dodge such issues. </off-topic>
--
Eric Sosman
esosman@ieee-dot-org.invalid
.
|
|
|
| User: "" |
|
| Title: Re: memset |
28 Jan 2008 03:09:08 PM |
|
|
In article <QKOdnRBFGboHLwbanZ2dnUVZ_ournZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
For very large arrays that need to be filled/refilled very
many times, here's a function I cooked up long ago:
#include <string.h>
void fillmem(void *pdest, size_t sdest,
const void *pfrom, size_t sfrom)
/*
* Fills the `sdest' bytes starting at `pdest' with copies
* of the `sfrom' bytes starting at `pfrom'. The final copy
* will be partial if `sfrom' does not divide `sdest'.
*/
{
if (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pfrom = pdest;
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
while (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
sfrom += sfrom;
}
}
memcpy (pdest, pfrom, sdest);
}
<off-topic> At first glance and even at second glance, this looks
like a cache-killer. But on the platforms I've tested it doesn't
appear to suffer from cache-aliasing problems. It seems likely
that memcpy() on these platforms is implemented cleverly (and non-
portably) to dodge such issues. </off-topic>
How 'bout something like this?
--------
void fillmem(void *pdest,size_t sdest,const void *pfrom,size_t sfrom)
{
if(sdest <= sfrom)
{
memcpy(pdest,pfrom,sdest);
return;
}
/*Make the first copy of from*/
memcpy(pdest,pfrom,sfrom);
/*Now make the rest of the copies from the last copy
we made
*/
memmove((char *)pdest + sfrom,pdest,sdest-sfrom);
}
--------
I would expect this to be more cache-friendly[1], since after the
initial copy it's (in the abstract, at least) a simple linear walk
through memory for each of read and write, instead of walking through
the beginning of the array log2(N) times (going farther each time).
This takes advantage of the defined-on-overlap semantics of memmove; is
losing any optimizations memcpy can make that memmove can't a
sufficiently low price to pay for any benefits this approach might
have?
(Interestingly, I invented this independently about a week before
reading a description in comp.arch of the same technique being used in
a system older than I am.)
dave
[1] Keeping in mind that I know next to nothing about caching behavior
of modern processors
--
Dave Vandervies dj3vande at eskimo dot com
BTW, bottlenecks are Good: Unless I can find one or a few, speeding up a
procedure/algorithm/program is _much_ harder.
--Terje Mathisen in comp.arch
.
|
|
|
| User: "Eric Sosman" |
|
| Title: Re: memset |
28 Jan 2008 05:17:26 PM |
|
|
dj3vande@csclub.uwaterloo.ca.invalid wrote:
In article <QKOdnRBFGboHLwbanZ2dnUVZ_ournZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
For very large arrays that need to be filled/refilled very
many times, here's a function I cooked up long ago:
#include <string.h>
void fillmem(void *pdest, size_t sdest,
const void *pfrom, size_t sfrom)
/*
* Fills the `sdest' bytes starting at `pdest' with copies
* of the `sfrom' bytes starting at `pfrom'. The final copy
* will be partial if `sfrom' does not divide `sdest'.
*/
{
if (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pfrom = pdest;
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
while (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
sfrom += sfrom;
}
}
memcpy (pdest, pfrom, sdest);
}
<off-topic> At first glance and even at second glance, this looks
like a cache-killer. But on the platforms I've tested it doesn't
appear to suffer from cache-aliasing problems. It seems likely
that memcpy() on these platforms is implemented cleverly (and non-
portably) to dodge such issues. </off-topic>
How 'bout something like this?
--------
void fillmem(void *pdest,size_t sdest,const void *pfrom,size_t sfrom)
{
if(sdest <= sfrom)
{
memcpy(pdest,pfrom,sdest);
return;
}
/*Make the first copy of from*/
memcpy(pdest,pfrom,sfrom);
/*Now make the rest of the copies from the last copy
we made
*/
memmove((char *)pdest + sfrom,pdest,sdest-sfrom);
}
memmove() doesn't "smear" the data the way this needs it
to. You'll end up with two copies of the fill pattern followed
by a big blob of whatever was in the destination beforehand,
slid rightwards by sfrom bytes.
7.21.2.2p2: "[...] Copying takes place as if the n
characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does
not overlap the objects pointed to by s1 and s2, and
then the n characters from the temporary array are copied
into the object pointed to by s1."
(Interestingly, I invented this independently about a week before
reading a description in comp.arch of the same technique being used in
a system older than I am.)
This technique for "smearing" has been around since the days
of the dawn; I first encountered it in 1966 as a clear-core
program that was one instruction long. But that's not what
memmove() does.
--
Eric Sosman
esosman@ieee-dot-org.invalid
.
|
|
|
| User: "" |
|
| Title: Re: memset |
28 Jan 2008 05:42:03 PM |
|
|
In article <69mdnSKSefso_wPanZ2dnUVZ_tWtnZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
memmove() doesn't "smear" the data the way this needs it
to. You'll end up with two copies of the fill pattern followed
by a big blob of whatever was in the destination beforehand,
slid rightwards by sfrom bytes.
7.21.2.2p2: "[...] Copying takes place as if the n
characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does
not overlap the objects pointed to by s1 and s2, and
then the n characters from the temporary array are copied
into the object pointed to by s1."
Hmmmmmmm....
I could've sworn that said something different last time I read it,
which must have been too many lost neurons ago.
I suppose it's a Good Thing you pointed that out before I got around to
finishing the project I was planning to use it in, then.
This technique for "smearing" has been around since the days
of the dawn; I first encountered it in 1966 as a clear-core
program that was one instruction long. But that's not what
memmove() does.
Is there a reason (well, a reason behind history, which is probably the
currently-live reason) why memmove does a non-destructive copy instead
of smearing? It seems, to my limited imagination, that smearing would
be a lot more useful.
dave
--
Dave Vandervies dj3vande at eskimo dot com
Effectively, Microsoft creates good programming the same way that sand
grains create pearls - through irritating someone else. And Microsoft has
a lot of sand. --SteveD in the scary devil monastery
.
|
|
|
| User: "CBFalconer" |
|
| Title: Re: memset |
29 Jan 2008 04:39:48 PM |
|
|
dj3vande@csclub.uwaterloo.ca.invalid wrote:
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
.... snip ...
7.21.2.2p2: "[...] Copying takes place as if the n
characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does
not overlap the objects pointed to by s1 and s2, and
then the n characters from the temporary array are copied
into the object pointed to by s1."
.... snip ...
Is there a reason (well, a reason behind history, which is
probably the currently-live reason) why memmove does a non-
destructive copy instead of smearing? It seems, to my limited
imagination, that smearing would be a lot more useful.
If you examine Erics quote with care, you will notice the magic
phrase "as if". The thing that counts is the end result.
--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com
.
|
|
|
| User: "" |
|
| Title: Re: memset |
30 Jan 2008 09:49:39 AM |
|
|
In article <479FAB34.DAB81B64@yahoo.com>,
CBFalconer <cbfalconer@maineline.net> wrote:
dj3vande@csclub.uwaterloo.ca.invalid wrote:
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
... snip ...
7.21.2.2p2: "[...] Copying takes place as if the n
characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does
not overlap the objects pointed to by s1 and s2, and
then the n characters from the temporary array are copied
into the object pointed to by s1."
... snip ...
Is there a reason (well, a reason behind history, which is
probably the currently-live reason) why memmove does a non-
destructive copy instead of smearing? It seems, to my limited
imagination, that smearing would be a lot more useful.
If you examine Erics quote with care, you will notice the magic
phrase "as if". The thing that counts is the end result.
Yes.
My question was why it wasn't "as if by a simple byte-copying loop".
i.e. why the specified end result was what it is instead of something
else.
(Interestingly, the day after I claimed elsethread that I've
never-in-my-memory had a reason to use memmove, I ended up doing
exactly the array-shift that Eric used as an example of what it's
useful for. The universe definitely has a sense of humour this week.)
dave
--
Dave Vandervies dj3vande at eskimo dot com
I like "fun" risks, rather than "lazy" risks.
(If I'm going to kill myself, I want to have a good time on the way.)
--Graham Reed in the scary devil monastery
.
|
|
|
|
|
| User: "Eric Sosman" |
|
| Title: Re: memset |
29 Jan 2008 07:31:25 AM |
|
|
dj3vande@csclub.uwaterloo.ca.invalid wrote:
[...]
Is there a reason (well, a reason behind history, which is probably the
currently-live reason) why memmove does a non-destructive copy instead
of smearing? It seems, to my limited imagination, that smearing would
be a lot more useful.
memmove() copies N bytes from source to destination.
The bytes that land in the destination are duplicates of
those that were in the source prior to the operation. So,
for example, you can use it to open a gap in an array:
memmove (array+C+i, array+C, (N-C-i) * sizeof array[0]);
.... or to close a gap:
memmove (array+C, array+C+i, (N-C-i) * sizeof array[0]);
With the "smearing" semantics -- which we've seen can be
obtained by other means -- these wouldn't work.
Look at it this way: memmove() and memcpy() "do the same
thing," except that the former promises to behave nicely even
when source and destination overlap, while the latter doesn't.
--
Eric Sosman
esosman@ieee-dot-org.invalid
.
|
|
|
| User: "" |
|
| Title: Re: memset |
29 Jan 2008 01:27:59 PM |
|
|
In article <FoqdnVi36JRDtwLanZ2dnUVZ_t2inZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
Look at it this way: memmove() and memcpy() "do the same
thing," except that the former promises to behave nicely even
when source and destination overlap, while the latter doesn't.
I think the source of my confusion may have been combining this with
understanding the behavior of memcpy as "copies as if by a simple
byte-copying loop" rather than "makes a duplicate copy".
The two behaviors are equivalent for non-overlapping chunks of memory,
but a simple byte-copying loop with (char*)src < (char*)dest <
(char*)src+size would do a smearing copy, while "making a duplicate
copy" excludes smearing by definition.
(It should be obvious by now that I rarely (never, as far as I can
remember) have to copy data between overlapping chunks of memory.)
dave
--
Dave Vandervies dj3vande at eskimo dot com
I really really wish Larry Wall was a native speaker of some language that
actually had rules. --Peter da Silva in the Scary Devil Monastery
.
|
|
|
|
|
|
|
|
|
|
| User: "Martin Vuille" |
|
| Title: Re: memset |
26 Jan 2008 03:24:26 PM |
|
|
Gaijinco <gaijinco@gmail.com> wrote in
news:a1148788-04c6-4a1b-8abe-ba7ffac20c95@c23g2000hsa.googlegrou
ps.com:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is
something else I have to do?.
In various computers that I have tried it seems that the only
value I can copy to a range with memset() that works is 0.
Thanks.
What you are trying to do will only work if sizeof( int ) == 1 in
your environment.
memset() manipulates bytes. If sizeof( int ) == 4 in your
environment, then each element of v will be set to 0x01010101.
MV
--
I do not want replies; please follow-up to the group.
.
|
|
|
|
| User: "William Ahern" |
|
| Title: Re: memset |
26 Jan 2008 03:38:01 PM |
|
|
Gaijinco <gaijinco@gmail.com> wrote:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
Mental exercise:
What's the difference, and expected result, of
char v[1000000];
memset(v, 1, sizeof v);
Hint: How does memset() know the stride when setting each element in the
array? Particularly given that in your example you explicitly cast the array
to a void pointer. Do you believe that memset() actually possesses this sort
of magic? It certainly _could_, cast or not, notwithstanding the correct
answer.
The precise answer is much more involved, of course.
.
|
|
|
|
| User: "Martin Ambuhl" |
|
| Title: Re: memset |
26 Jan 2008 03:28:19 PM |
|
|
Gaijinco wrote:
I'm having a headache using memset()
Given:
int v[1000000];
You have no guarantee that v can be that large.
memset((void*)v, 1, sizeof(v));
The cast to (void *) is just typing practice. Lose it.
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
Unless sizeof(int) == 1, you can be 100% positive that v[i] != 1.
Each of the sizeof(v) bytes, interpreted as unsigned chars, will have 1
stored in it. That means, on a binary machine, that each of the v[i]
will have sizeof(int) bits set. With the exception for sizeof(int) == 1,
that value cannot be 1.
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
You are completely wrong. Note the recurring patterns in the output
from the following program:
#include <stdio.h>
#include <string.h>
int main(void)
{
unsigned int v;
unsigned int i;
printf("Output on an implementation with sizeof(int) = %zu\n\n",
sizeof(int));
for (i = 0; i < 17; i++) {
printf("Setting each byte in the unsigned int v to %#x:\n", i);
memset(&v, i, sizeof v);
printf(" %#0x\n", v);
}
return 0;
}
Output on an implementation with sizeof(int) = 4
Setting each byte in the unsigned int v to 0:
0
Setting each byte in the unsigned int v to 0x1:
0x1010101
Setting each byte in the unsigned int v to 0x2:
0x2020202
Setting each byte in the unsigned int v to 0x3:
0x3030303
Setting each byte in the unsigned int v to 0x4:
0x4040404
Setting each byte in the unsigned int v to 0x5:
0x5050505
Setting each byte in the unsigned int v to 0x6:
0x6060606
Setting each byte in the unsigned int v to 0x7:
0x7070707
Setting each byte in the unsigned int v to 0x8:
0x8080808
Setting each byte in the unsigned int v to 0x9:
0x9090909
Setting each byte in the unsigned int v to 0xa:
0xa0a0a0a
Setting each byte in the unsigned int v to 0xb:
0xb0b0b0b
Setting each byte in the unsigned int v to 0xc:
0xc0c0c0c
Setting each byte in the unsigned int v to 0xd:
0xd0d0d0d
Setting each byte in the unsigned int v to 0xe:
0xe0e0e0e
Setting each byte in the unsigned int v to 0xf:
0xf0f0f0f
Setting each byte in the unsigned int v to 0x10:
0x10101010
.
|
|
|
| User: "Army1987" |
|
| Title: Re: memset |
27 Jan 2008 07:30:47 AM |
|
|
Martin Ambuhl wrote:
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
Unless sizeof(int) == 1, you can be 100% positive that v[i] != 1.
Let's say 99.99999999%, since it is possible that the least significant bit
of each byte except one of them is a padding bit.
--
Army1987 (Replace "NOSPAM" with "email")
.
|
|
|
|
|
| User: "Pedro Graca" |
|
| Title: Re: memset |
26 Jan 2008 04:29:17 PM |
|
|
Gaijinco wrote:
I'm having a headache using memset()
int v[100];
memset(v, 1, sizeof v);
How many times are you copying the 1?
It is not 100 times!
----------------
#include <stdio.h>
int main(void) {
int v[100];
/* sorry about the cast: my compiler doesn't like %zu */
printf("sizeof v is %lu.\n", (unsigned long)sizeof v);
return 0;
}
----------------
If you copy 400 values of 1 into v, you cannot expect each of the
values to be 1 :)
.
|
|
|
|
| User: "Jack Klein" |
|
| Title: Re: memset |
26 Jan 2008 03:31:41 PM |
|
|
On Sat, 26 Jan 2008 13:02:39 -0800 (PST), Gaijinco
<gaijinco@gmail.com> wrote in comp.lang.c:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
No need for the cast to void pointer here, the conversion is
automatic. But do make sure to include <string.h>. Also there is no
need for the parentheses abound the 'v' as an operand to the sizeof
operator, as 'v' is an object, not a type.
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
No you can't, and on most implementations it will not be. memset()
will place the value 1 into every byte that makes up the array, and
there are 1,000,000 times sizeof (int) bytes in the array.
There are a few implementations, mostly digital signal processors,
where CHAR_BIT is 16 and char and int have the same size and
representation, where every int in the array will be set to the value
1.
But on most platforms, especially anything in a desktop computer, you
won't get that value.
On old 16-bit implementations for MS-DOS, each int in the array will
wind up with the value 257.
On 32-bit Windows, Macintosh, or Linux platforms using x86 processors,
each int in the array will have the value 16843009.
On 64-bit operating systems using x86, the result will be
72340172838076673.
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
It works for a value of 0 because memset() with a value of 0 will set
every bit in every byte to all bits 0. C guarantees that any integer
type with a value of all bits 0 has the value 0. This is not
guaranteed for floating point types or pointers.
As to how to do it, you need to use a loop:
#define ARRAY_SIZE 1000000
int v [ARRAY_SIZE];
size_t index;
for (index = 0; index < ARRAY_SIZE]; ++index)
{
v [index] = 1;
}
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
.
|
|
|
| User: "Billy Bong" |
|
| Title: Re: memset |
29 Jan 2008 01:21:53 AM |
|
|
On Sat, 26 Jan 2008 15:31:41 -0600, Jack Klein wrote:
On Sat, 26 Jan 2008 13:02:39 -0800 (PST), Gaijinco <gaijinco@gmail.com>
wrote in comp.lang.c:
I'm having a headache using memset()
Given:
int v[1000000];
memset((void*)v, 1, sizeof(v));
No need for the cast to void pointer here, the conversion is automatic.
But do make sure to include <string.h>. Also there is no need for the
parentheses abound the 'v' as an operand to the sizeof operator, as 'v'
is an object, not a type.
Can I be 100% positive than v[i] = 1 for i > 0, or there is something
else I have to do?.
No you can't, and on most implementations it will not be. memset() will
place the value 1 into every byte that makes up the array, and there are
1,000,000 times sizeof (int) bytes in the array.
There are a few implementations, mostly digital signal processors, where
CHAR_BIT is 16 and char and int have the same size and representation,
where every int in the array will be set to the value 1.
But on most platforms, especially anything in a desktop computer, you
won't get that value.
On old 16-bit implementations for MS-DOS, each int in the array will
wind up with the value 257.
On 32-bit Windows, Macintosh, or Linux platforms using x86 processors,
each int in the array will have the value 16843009.
On 64-bit operating systems using x86, the result will be
72340172838076673.
In various computers that I have tried it seems that the only value I
can copy to a range with memset() that works is 0.
It works for a value of 0 because memset() with a value of 0 will set
every bit in every byte to all bits 0. C guarantees that any integer
type with a value of all bits 0 has the value 0. This is not guaranteed
for floating point types or pointers.
As to how to do it, you need to use a loop:
#define ARRAY_SIZE 1000000
int v [ARRAY_SIZE];
size_t index;
for (index = 0; index < ARRAY_SIZE]; ++index) {
v [index] = 1;
}
Sans the extraneous ']' character after ARRAY_SIZE in the above for loop
(which requires a compiler diagnostic, and which is obviously a typo by
Mr. Klein), this is the way to do it.
If you want to initialize an array and do it in a portable, Standard C
compliant way, then using a for loop as above will guarantee this. Using
memset will not always guarantee this.
This should be a part of everyone's coding standard:
In code, always use a for loop (instead of, for example, memset) to
initialize an array.
--
Billy
.
|
|
|
| User: "Richard Heathfield" |
|
| Title: Re: memset |
29 Jan 2008 02:23:34 AM |
|
|
[comp.std.c added, no followups set - can we keep this in both groups
please? Ta.]
Billy Bong said:
On Sat, 26 Jan 2008 15:31:41 -0600, Jack Klein wrote:
<snip>
int v [ARRAY_SIZE];
size_t index;
for (index = 0; index < ARRAY_SIZE]; ++index) {
v [index] = 1;
}
Sans the extraneous ']' character after ARRAY_SIZE in the above for loop
(which requires a compiler diagnostic, and which is obviously a typo by
Mr. Klein), this is the way to do it.
If you want to initialize an array and do it in a portable, Standard C
compliant way, then using a for loop as above will guarantee this. Using
memset will not always guarantee this.
....unless the array is of objects with integer type and the value you wish
to write into the array is 0, as we are assured from time to time by
various ISO members. This cannot AFAIK be deduced directly from the
Standard, though. Did it ever make it as far a TC?
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
.
|
|
|
| User: "Army1987" |
|
| Title: Re: memset |
29 Jan 2008 09:38:20 AM |
|
|
Richard Heathfield wrote:
...unless the array is of objects with integer type and the value you wish
to write into the array is 0, as we are assured from time to time by
various ISO members. This cannot AFAIK be deduced directly from the
Standard, though. Did it ever make it as far a TC?
n1256 in 6.2.6.2p5 has: A valid (non-trap) object representation
of a signed integer type where the sign bit is zero is a valid object representation of the
corresponding unsigned type, and shall represent the same value. For any integer type,
the object representation where all the bits are zero shall be a representation of the value
zero in that type.
There are change bars beside the last sentence.
See http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_263.htm
--
Army1987 (Replace "NOSPAM" with "email")
.
|
|
|
| User: "Richard Heathfield" |
|
| Title: Re: memset |
29 Jan 2008 10:58:16 AM |
|
|
Army1987 said:
Richard Heathfield wrote:
...unless the array is of objects with integer type and the value you
wish to write into the array is 0, as we are assured from time to time
by various ISO members. This cannot AFAIK be deduced directly from the
Standard, though. Did it ever make it as far a TC?
n1256 in 6.2.6.2p5 has: A valid (non-trap) object representation
of a signed integer type where the sign bit is zero is a valid object
representation of the corresponding unsigned type, and shall represent
the same value. For any integer type, the object representation where
all the bits are zero shall be a representation of the value zero in
that type.
There are change bars beside the last sentence.
See http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_263.htm
Well, that answers that. Thanks, Army1987.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
.
|
|
|
|
|
| User: "Spoon root@localhost" |
|
| Title: Re: memset |
29 Jan 2008 09:23:06 AM |
|
|
Richard Heathfield wrote:
[comp.std.c added, no followups set - can we keep this in both
groups please? Ta.]
I don't think you added comp.std.c
.
|
|
|
| User: "Richard Heathfield" |
|
| Title: Re: memset |
29 Jan 2008 10:57:38 AM |
|
|
Spoon said:
Richard Heathfield wrote:
[comp.std.c added, no followups set - can we keep this in both
groups please? Ta.]
I don't think you added comp.std.c
Oh FOO BAR BAZ, you're right. Oh well... :-)
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
.
|
|
|
|
|
|
|
|

|
Related Articles |
|
|