having hard time to understand the way memset() works. Does the Standard
(I'm interested in both C90 and C99) guarantee that the function will set to
0 all the bits of the structure's members ?
Does the memset() act differently if a structure integrates unions ?
Quoting ISO C99: "The memset function copies the value of c (converted to an
unsigned char) into each of the first n characters of the object pointed to
by s.", but as I understand this rule does not apply if the object is, say,
an array of 'ints' with sizeof(int) > 1. Perhaps I don't get it right at
all.
Thanks.
--
Mark
memset treats its argument as a bucket of bytes, it is not aware of the
type (hence the use of a void*.
> Does the memset() act differently if a structure integrates unions ?
No.
> Quoting ISO C99: "The memset function copies the value of c (converted
> to an unsigned char) into each of the first n characters of the object
> pointed to by s.", but as I understand this rule does not apply if the
> object is, say, an array of 'ints' with sizeof(int) > 1. Perhaps I don't
> get it right at all.
You have to specify the size of the object in bytes. For example if you
have an array of ints someSize long:
memset( yourArray, 0, someSize*sizeof(int) );
--
Ian Collins
The memset function knows nothing about your structures and its
members, it simply sets all the bytes in a given "range" to a given
value. If the value is 0, and the "range" covers some object of a
struct type, then yes, all the bits of the structure's members will be
set to 0.
However, this doesn't mean the structure's members themselves will be
set to 0. The standard requires that all integral-typed objects having
all their bits set to 0 are themselves equal to 0, but the
representation of pointers and floating-point is unspecified, and
therefore - at least theoretically - having all their bits set to 0 is
not necessarily equivalent to having themselves equal to 0.
For example:
struct X
{
char a;
int b;
double c;
void* d;
} x;
memset(&x, 0, sizeof x);
printf("%d %d %f %d", x.a, x.b, x.c, x.d != NULL);
This will print two zeroes for x.a and x.b and two more values for x.c
and x.d which are most likely zeroes on mainstream platforms but not
necessarily. To be pedantic, the code above has undefined behaviour
because access to the values of x.c and x.d which at the point of
access are not properly initialized. However, on mainstream platforms
this will work perfectly OK.
> Does the memset() act differently if a structure integrates unions ?
C has no reflection, so memset knows nothing about structures and
unions. All it knows about is memory which is made up by a sequence of
bytes.
struct X
{
char a;
union
{
int b;
double c;
void* d;
};
} x;
memset(&x, 0, sizeof x);
printf("%d %d %f %d", x.a, x.b, x.c, x.d != NULL);
This code will yield the same output as above (and all the
reservations are valid as well). Members x.b, x.c and x.d are
overlapping in the memory this time; but the bytes allocated to them
are still all zeroes.
> Quoting ISO C99: "The memset function copies the value of c (converted to an
> unsigned char) into each of the first n characters of the object pointed to
> by s.", but as I understand this rule does not apply if the object is, say,
> an array of 'ints' with sizeof(int) > 1. Perhaps I don't get it right at
> all.
Why not? Arrays are placed in the memory contiguously, therefore you
can use memset to initialize arrays as well.
int i, x[100];
memset(&x, 0, sizeof x);
for (i = 0; i < 100; ++i) printf("%d ", x[i]);
This yields 100 zeroes. Assume, for example, that sizeof (int) == 4.
400 bytes are allocated for the array x. memset sets these 400 (sizeof
x) bytes to 0. Access to any x[i] retrives corresponding 4 bytes out
of those 400, and those 4 bytes are all 0, making up the int value of
0.
This is from the thread named "Initialising an array".
"Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
news:hk45dr$6ri$1...@news.eternal-september.org...
>> Also you can try the standard function memset:
>>
>> int par[MAX];
>> memset(par, INT_MAX, MAX);
>
... except that this will only work if sizeof(int) == 1.
Even if you change the third argument to sizeof(int) * MAX
(or to sizeof par), this can work for only a few of the
possible values one might want in an int, and only then by
lucky (unlucky?) chance.
Doesn't this mean that "memset( yourArray, 0, someSize*sizeof(int) )" isn't
always guaranteed to zero up all the bits? Perhaps I misunderstood Mr.
Sosman's comment.
--
Mark
Well, if used with a 0, yes.
> Quoting ISO C99: "The memset function copies the value of c (converted to an
> unsigned char) into each of the first n characters of the object pointed to
> by s.", but as I understand this rule does not apply if the object is, say,
> an array of 'ints' with sizeof(int) > 1. Perhaps I don't get it right at
> all.
Sure it does. It's just that there's not necessarily a guarantee that
all-bits-zero will be a useful state for an object other than an unsigned
char.
-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
The difference is that INT_MAX is probably not expressable in an unsigned
char (unless sizeof(int) is 1), but 0 is.
Here's the thing. Let's say you're on a 32-bit twos complement
system, with 8-bit chars.
int i;
memset(&i, INT_MAX, sizeof(int));
What does this do? Well, it computes the value of INT_MAX, which is
0x7fffffff, then converts that to unsigned char, yielding 0xff, then sets
each byte of i to 0xff, yielding 0xffffffff. Which is not the same as
0x7fffffff. Similarly:
int i[MAX];
memset(i, 0, MAX);
will set the first MAX bytes -- but i[MAX] is sizeof(int)*MAX bytes in
length, so it won't affect the whole array unless sizeof(int) == 1.
memset just treats everything as a bag of bytes. It has no way of knowing
whether the things you're pointing it at are something else, so it doesn't
care.
"memset( yourArray, 0, someSize*sizeof(int) )" shall always zero up
all the bits.
memset casts its second argument to unsigned char internally. Casting
zero always yields zero because it is a value which is for sure
representable in all integral types. Casting INT_MAX to unsigned char
is different, unsigned char simply cannot represent INT_MAX unless
sizeof (int) == 1. On a typical platform where sizeof (int) == 4,
INT_MAX is 0x7FFFFFFF, and (unsigned char)INT_MAX is 0xFF.
...than an integer type.
C90 implicitly guaranteed it for all integers, C99 (as of
one of the TCs) explicitly guarantees it.
N1256, 6.2.6.2p5: "...For any integer type, the object
representation where all the bits are zero shall be a
representation of the value zero in that type."
--
Peter
Oooh, shiny. And very handy.
Well, that was the last thing stopping ME from taking over the world.
When I crush nations under my feet, I shall remember you fondly.
Please refrain from using outmoded, idiosyncratic and
purely local terms in describing your forthcoming conquest.
The accepted International Standard language would be "When
I crush nations under my meters ..."
--
Eric Sosman
eso...@ieee-dot-org.invalid
> Please refrain from using outmoded, idiosyncratic and
>purely local terms in describing your forthcoming conquest.
>The accepted International Standard language would be "When
>I crush nations under my meters ..."
Surely the International Standard spelling is "metres".
-- Richard
--
Please remember to mention me / in tapes you leave behind.
With memset() you can fill a region of memory with all
zeroes, or with all ones, or with copies of any single byte
value. (Whether these are meaningful for the data objects
contained in that region is another matter.) What you can't
do is fill a region with a pattern of non-identical bytes.
In the other thread, the question was about setting all the
elements of an int[] to the value INT_MAX, and my point was
that INT_MAX very likely involves non-identical bytes: some
mixture of 0x7F and 0xFF is quite common, and may even be
universal.
If you want to fill a region with a "patterned" value, you
may be interested in this function I wrote 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) {
/* Put one copy of the source pattern at the start of
* the destination.
*/
memcpy (pdest, pfrom, sfrom);
pfrom = pdest;
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
/* Copy data from the beginning of the destination to the
* end, with each iteration doubling the amount copied.
*/
while (sdest > sfrom) {
memcpy (pdest, pfrom, sfrom);
pdest = (char*)pdest + sfrom;
sdest -= sfrom;
sfrom += sfrom;
}
}
/* Fill the final (or only) piece of the destination.
*/
memcpy (pdest, pfrom, sdest);
}
The loop looks like it could be a cache-killer, but I haven't
seen evidence of bad behavior on the machines where I've used it.
YMMV, the Secretary will disclaim, etc., etc.
--
Eric Sosman
eso...@ieee-dot-org.invalid
>> Please refrain from using outmoded, idiosyncratic and
>>purely local terms in describing your forthcoming conquest.
>>The accepted International Standard language would be "When
>>I crush nations under my meters ..."
>
> Surely the International Standard spelling is "metres".
British spelling: "metre"
US spelling: "yard"
>British spelling: "metre"
>US spelling: "yard"
A metre is about 11/10 of a yard. Apparently Napoleon was a Spinal
Tap fan, and wanted his metres to go to 11.
I believe you'll find the international spelling to be "meter" except
perhaps in Paris. And we know the French can't spell. Chien Chaud indeed.
--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
A meter is what you have under the stairs.
A metre is 1000/25.4 inches.
--
Bartc
A meter is not defined in inches, rather the other way around. An inch is
25.4 millimeters, exactly. Napolean won that war.
> Look up "metre" in any dictionary you have to hand. You will be
> referred to "meter" is every case. Even La Rousse.
By co-incidence I had Chamber's dictionary sitting such that I could
pick it up without moving in or from my seat. That's about as "to hand"
as you could get.
So I looked up "metre". Here's the first couple of lines of the entries
(with some adaptation for ASCII only):
"*metre*(1) or (US) *meter* [pronunciation] /n/ the regulated succession
of groups of syllables ...."
"*metre*(2) or (US) *meter* [pronunciation] /n/ the fundamental unit of
length in the metric system ...
It appears that you're wrong.
Just to really confirm this, there are two entries for "meter". The
first is "a measurer, an apparatus for measuring" and the second I quote
in it's entirety:
"*Meter*(2) US spelling of *metre*(1,2)
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
> >>>> Please refrain from using outmoded, idiosyncratic and
> >>>> purely local terms in describing your forthcoming conquest.
> >>>> The accepted International Standard language would be "When
> >>>> I crush nations under my meters ..."
>
> >>> Surely the International Standard spelling is "metres".
>
> >>> -- Richard
>
> >> I believe you'll find the international spelling to be "meter" except
> >> perhaps in Paris. And we know the French can't spell. Chien Chaud indeed.
>
> > A meter is what you have under the stairs.
>
> > A metre is 1000/25.4 inches.
>
> Look up "metre" in any dictionary you have to hand. You will be referred to
> "meter" is every case. Even La Rousse.
wikipedia have this to say "Two spellings of the name of the unit are
common in English: metre is preferred among the majority of countries
in the English-speaking world except in the United States, where the
spelling is meter"
I'm not happy about the adoption of the yard. Rods, Poles and Perch
are good enough for anyone!
God used the cubit why should we use anything else?
...most excellent.
> > I believe you'll find the international spelling to be "meter" except
> > perhaps in Paris. And we know the French can't spell. Chien Chaud indeed.
>
> A meter is what you have under the stairs.
>
> A metre is 1000/25.4 inches.
Yep. Metre is the spelling used in Commonwealth countries, but I'm
familiar with both to the point that I sometimes interchange between
them when writing; a bad habit I know.
>Look up "metre" in any dictionary you have to hand. You will be referred to
>"meter" is every case.
The OED gives "meter" as an alternative spelling under "metre", and
describes it as "chiefly U.S.".
> Nobody <nob...@nowhere.com> wrote:
>
> >British spelling: "metre"
> >US spelling: "yard"
>
> A metre is about 11/10 of a yard.
Don't tell NASA that.
Richard