memset doubt

S

srivatsan_b

Hi,

Can somebody explain whether an explicit typecast is mandatory while
calling memset function for a structure? like in the following code
snapshot.....
struct some_structure x;
memset((some_structure*)&x,0,sizeof(some_structure));
Will memset(&x,0,sizeof(some_structure)); cause some issues?

Thanks in advance
Srivatsan
 
P

Peter Nilsson

srivatsan_b said:
Hi,

Can somebody explain whether an explicit typecast is mandatory while
calling memset function for a structure? like in the following code
snapshot.....
struct some_structure x;
memset((some_structure*)&x,0,sizeof(some_structure));
Will memset(&x,0,sizeof(some_structure)); cause some issues?

Slightly better is... memset(&x, 0, sizeof x);

In C, there is an issue, but it's not the issue you're asking about.

In C, any object pointer can be implicitly converted to a pointer
to void [subject to cv-qualifiers.] So the answer to your question
is no. C++ is different, but you should ask in a C++ group if you
ere actually using a C++ compiler.

Where you may have problems is that setting all the bits of the
structure contents to zero, may not do what you want. If your
structure contains pointers for instance, then setting the bits to
0 need not set them to null pointers.

If you want to zero initialise a structure (or indeed any other
object type), then you simply need to do...

struct some_structure x = { 0 };

No memset is required.
 
K

Keith Thompson

srivatsan_b said:
Can somebody explain whether an explicit typecast is mandatory while
calling memset function for a structure? like in the following code
snapshot.....
struct some_structure x;
memset((some_structure*)&x,0,sizeof(some_structure));
Will memset(&x,0,sizeof(some_structure)); cause some issues?

Assuming that you've remembered to #include <string.h>, which declares
the memset() function, the cast is unnecessary. Any object pointer
type can be implicitly converted to void*, and vice versa.

There are a couple of problems with your code, one serious and one
cosmetic.

Given a declaration of "struct some_structure", there is no type
called "some_structure"; the struct keyword is necessary unless you've
also declared it as a typedef. (Some would argue that typedefs for
struct types are poor style.)

<OT>
Note that the rules are different for C++. If I recall correctly, a
declaration of "struct some_structure" makes "some_structure" visible
as a type name, and there is no implicit conversion to void*. That
shouldn't be relevant unless you're using a C++ compiler -- and if you
are, you're in the wrong newsgroup.
</OT>

Also, using the size of the object makes for cleaner code than using
the size of the type. For example:

struct some_structure x;
memset(&x, 0, sizeof x);

Not only is this shorter, it avoid errors if the type of x is changed.
 
B

Barry Schwarz

Hi,

Can somebody explain whether an explicit typecast is mandatory while
calling memset function for a structure? like in the following code
snapshot.....
struct some_structure x;
memset((some_structure*)&x,0,sizeof(some_structure));
Will memset(&x,0,sizeof(some_structure)); cause some issues?

Firstly, &x already has type pointer to struct some_structure.
Therefore, casting any value to the same type it already has is by
definition redundant.

Secondly, memset expects the first argument to have type pointer to
void. If you were going to cast the value, that is what you would
cast it to.

Thirdly, pointer to void is "compatible" with any other unqualified
object pointer type. This means that the compiler can implicitly
convert one to the other whenever it needs to without requiring a
cast.

The only problem with your final question is that for C89 compilers
the cast must include the keyword struct. The use of the structure
tag without the keyword did not become standard until C99 and there
are very few compilers of that grade in use.


<<Remove the del for email>>
 
K

Keith Thompson

Barry Schwarz said:
On 30 Aug 2005 22:43:54 -0700, "srivatsan_b" <[email protected]>
wrote: [...]
The only problem with your final question is that for C89 compilers
the cast must include the keyword struct. The use of the structure
tag without the keyword did not become standard until C99 and there
are very few compilers of that grade in use.

No, a declaration of "struct foo" doesn't make just "foo" visible as a
type name in either C89 or C99. (It does in C++.)
 
E

Emmanuel Delahaye

srivatsan_b wrote on 31/08/05 :
Can somebody explain whether an explicit typecast is mandatory while

calling memset function for a structure? like in the following code
snapshot.....
struct some_structure x;
memset((some_structure*)&x,0,sizeof(some_structure));

Plain wrong. You meant:

struct some_structure x;
memset((struct some_structure*)&x,0, sizeof(struct some_structure));
Will memset(&x,0,sizeof(some_structure)); cause some issues?

No, as long as 'x' has the type 'some_structure'. This is why I prefer
to use the size of the the object itself.

memset (&x, 0, sizeof x);

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
 
T

Tim Rentsch

Barry Schwarz said:
Thirdly, pointer to void is "compatible" with any other unqualified
object pointer type. This means that the compiler can implicitly
convert one to the other whenever it needs to without requiring a
cast.

Just a minor correction. The word "compatible" is
used in the standard document following a particular
definition (section 6.2.7 p1, and others).

In the sense of this definition, void pointers and
non-void pointers are not "compatible". They can be
used interchangeably in many contexts, but they are
not "compatible" in the sense that the standard
document uses the word.
 
D

Default User

Peter Nilsson wrote:

In C, any object pointer can be implicitly converted to a pointer
to void [subject to cv-qualifiers.] So the answer to your question
is no. C++ is different, but you should ask in a C++ group if you
ere actually using a C++ compiler.

C++ is not different in this case. The difference is that void* can't
be converted to an object pointer without a cast.



Brian
 
D

Default User

Keith Thompson wrote:

<OT>
Note that the rules are different for C++. If I recall correctly, a
declaration of "struct some_structure" makes "some_structure" visible
as a type name,
Yes.

and there is no implicit conversion to void*.

No. There is no implicit conversion FROM void*. So malloc() needs a
cast, memset() doesn't.
 
T

Tim Rentsch

Lawrence Kirby said:
Perhaps the term "assignment compatible" is appropriate here. While not
strictly a standard term its meaning is clear.

I propose "implicitly convertible". It's descriptive,
and accurate.

Besides the confusion around "compatible", the term
"assignment compatible" suggests that the conversion
happens only for assignment (or function arguments);
whereas void pointers can also be used with non-void
pointers in other contexts, eg, equality comparisons,
or as one side of a ?: result set.
 
L

Lawrence Kirby

Just a minor correction. The word "compatible" is
used in the standard document following a particular
definition (section 6.2.7 p1, and others).

In the sense of this definition, void pointers and
non-void pointers are not "compatible". They can be
used interchangeably in many contexts, but they are
not "compatible" in the sense that the standard
document uses the word.

Perhaps the term "assignment compatible" is appropriate here. While not
strictly a standard term its meaning is clear.

Lawrence
 
C

Charlie Gordon

Peter Nilsson said:
Slightly better is... memset(&x, 0, sizeof x); ....
Where you may have problems is that setting all the bits of the
structure contents to zero, may not do what you want. If your
structure contains pointers for instance, then setting the bits to
0 need not set them to null pointers.

While this is true in theory from the words of the holy C99 norm, can you name
actual contemporary architectures where this is true in practice? What about
integral and floating point types? Any example of machines on which clearing
them to all bits zero is not advisable or does not produce 0 values?

DS9000 will not be accepted as an answer.
If you want to zero initialise a structure (or indeed any other
object type), then you simply need to do...

struct some_structure x = { 0 };

No memset is required.

how can you re-initialize it after use ?

Chqrlie.
 
A

Alf P. Steinbach

* Charlie Gordon:
how can you re-initialize it after use ?

static SomeStructure const someStructure0 = {};

SomeStructure x = {};
....
x = someStructure0;


Not that that it's generally a good idea to "re-initialize". Because that
implies a variable used for two or more different things. If such things
are systematically removed, the code generally becomes a lot cleaner.
 
C

Charlie Gordon

Alf P. Steinbach said:
* Charlie Gordon:

static SomeStructure const someStructure0 = {};

Can you omit the ={} initializer if this one is at file scope?
SomeStructure x = {};
...
x = someStructure0;

what about not using an explicit static variable.
can't you do this with an unnamed structure in C99?
Not that that it's generally a good idea to "re-initialize". Because that
implies a variable used for two or more different things. If such things
are systematically removed, the code generally becomes a lot cleaner.

I agree, but this structure might be part of a larger one.

Chqrlie.
 
J

Jack Klein

I propose "implicitly convertible". It's descriptive,
and accurate.

Besides the confusion around "compatible", the term
"assignment compatible" suggests that the conversion
happens only for assignment (or function arguments);
whereas void pointers can also be used with non-void
pointers in other contexts, eg, equality comparisons,
or as one side of a ?: result set.

What do you mean by equality comparisons? Are you implying code like
this:

#include <stdio.h>

int main(void)
{
int x = 0;
int *ip = &x;
void *vp = &x;
if (vp == ip)
puts("they match");
else
puts("they don't");
return x;
}

....is valid?
 
K

Keith Thompson

Jack Klein said:
On 31 Aug 2005 11:36:14 -0700, Tim Rentsch <[email protected]>
wrote in comp.lang.c: [...]
I propose "implicitly convertible". It's descriptive,
and accurate.

Besides the confusion around "compatible", the term
"assignment compatible" suggests that the conversion
happens only for assignment (or function arguments);
whereas void pointers can also be used with non-void
pointers in other contexts, eg, equality comparisons,
or as one side of a ?: result set.

What do you mean by equality comparisons? Are you implying code like
this:

#include <stdio.h>

int main(void)
{
int x = 0;
int *ip = &x;
void *vp = &x;
if (vp == ip)
puts("they match");
else
puts("they don't");
return x;
}

...is valid?

I believe it is. Are you implying that it isn't?

C99 6.5.9 Equality operators:

Constraints

One of the following shall hold:

-- both operands have arithmetic type;

-- both operands are pointers to qualified or unqualified versions
of compatible types;

-- one operand is a pointer to an object or incomplete type and
the other is a pointer to a qualified or unqualified version of
void; or

-- one operand is a pointer and the other is a null pointer constant.
 
T

Tim Rentsch

Jack Klein said:
What do you mean by equality comparisons? Are you implying code like
this:

#include <stdio.h>

int main(void)
{
int x = 0;
int *ip = &x;
void *vp = &x;
if (vp == ip)
puts("they match");
else
puts("they don't");
return x;
}

...is valid?

Yes. Did you try it? Keith Thompson quoted the relevant
section, 6.5.9, at least the Constraints part of it, in his
posting. (Thanks Keith.)
 
W

William Ahern

Can you omit the ={} initializer if this one is at file scope?

Of course. But, sometime's I'll include the braces as a stub. Often times I
need to go back and initialize some member(s) of the initializer with
non-zero values.
what about not using an explicit static variable.
can't you do this with an unnamed structure in C99?

yep

x = (SomeStructure){ 0 };
 
C

Charlie Gordon

William Ahern said:
Of course. But, sometime's I'll include the braces as a stub. Often times I
need to go back and initialize some member(s) of the initializer with
non-zero values.



yep

x = (SomeStructure){ 0 };

Is the 0 necessary in this case ?

Chqrlie.
 
M

Markus Becker

No. There is no implicit conversion FROM void*. So malloc() needs a
cast, memset() doesn't.

No, you can assign a void* to any type of pointer-variable. You only
need to cast malloc() when using C++.

</nitpick>

Markus
 

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

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top