Pointer initialization.

T

tuko

Hello kind people.

Can someone explain please the following code?

/* Create Storage Space For The Texture */
AUX_RGBImageRec *TextureImage[1]; /* Line 1*/
/* Set The Pointer To NULL */
memset(TextureImage,0,sizeof(void *)*1); /* Line 2*/

According to my knowledge in the first line
the TextureImage variable is declared as
an array of one pointer to AUX_RGBImageRec.

Here is my question.
I don't understand the second line at all.
Especially the sizeof(void *) *1 thing.
What does it mean?

The initialization of the array of Pointer
could be better like this
AUX_RGBImageRec *TextureImage[1] = {NULL};
Right? It has the same effect?

(I know the distinction, but let's assume
that NULL and 0 is translated as the same
thing for the moment.)

Many thanks for any help.
 
C

CBFalconer

tuko said:
Can someone explain please the following code?

/* Create Storage Space For The Texture */
AUX_RGBImageRec *TextureImage[1]; /* Line 1*/
/* Set The Pointer To NULL */
memset(TextureImage,0,sizeof(void *)*1); /* Line 2*/

According to my knowledge in the first line
the TextureImage variable is declared as
an array of one pointer to AUX_RGBImageRec.

It's stupid nonsense, to all practical purposes. Trust yourself
and write better and clearer code. What you probably want is:

AUX_RGBImageRec *TextureImage;
TextureImage = NULL;

without the misleading comments.
 
M

Martin Dickopp

tuko said:
Can someone explain please the following code?

/* Create Storage Space For The Texture */
AUX_RGBImageRec *TextureImage[1]; /* Line 1*/
/* Set The Pointer To NULL */
memset(TextureImage,0,sizeof(void *)*1); /* Line 2*/

The second line is problematic (see below) and doesn't do what the
comment suggests.
According to my knowledge in the first line
the TextureImage variable is declared as
an array of one pointer to AUX_RGBImageRec.
Yes.

Here is my question.
I don't understand the second line at all.
Especially the sizeof(void *) *1 thing.
What does it mean?

It yields the size of a generic object pointer, also known as pointer to
void. Multiplying `sizeof (void *)' with 1 has no effect.

The `memset' call therefore sets `sizeof (void *)' consecutive bytes,
starting from the address `TextureImage', to zero (i.e. it sets all bits
of these bytes to zero).
The initialization of the array of Pointer
could be better like this
AUX_RGBImageRec *TextureImage[1] = {NULL};
Right?

Yes. Alternatively, if an assignment instead of an initialization is
desired,

TextureImage [0] = NULL;

would work.
It has the same effect?

Well, no, the original code doesn't necessarily work correctly. It has
two problems. First of all, the `memset' call sets all bits to zero,
but that is not necessarily the correct representation of a null
pointer. OTOH, initialization with NULL or assignment of NULL always
sets the pointer to a null pointer, even if the internal representation
of a null pointer is /not/ all-bits-zero.

Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.
(I know the distinction, but let's assume
that NULL and 0 is translated as the same
thing for the moment.)

`NULL' is allowed to expand to `0', and wherever `NULL' is correct,
writing `0' instead is correct as well. In a context where a pointer is
needed, `0' is treated as a null pointer constant, not as the integer 0.

Martin
 
S

Stephen L.

Martin Dickopp wrote:

[ snip ]
Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.

Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!


Stephen
 
T

Thomas stegen

Stephen said:
Martin Dickopp wrote:

[ snip ]

Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.


Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

I might be.
So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!

It can be used even if they have different sizes. Or do you
think that you cannot pass a char to a function which expects
an int?
 
M

Martin Dickopp

Stephen L. said:
Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

I'm not saying that these sizes /must/ be different, but that they /can/
be different.
So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!

You can safely cast the pointers passed to the comparison function back
to the appropriate type (i.e. `AUX_RGBImageRec **' if you're sorting an
array of `AUX_RGBImageRec' pointers, or `AUX_RGBImageRec *' if you're
sorting an array of `AUX_RGBImageRec' objects). But that doesn't mean
that the pointer types have to have the same size. If the pointer types
have different representations, the cast converts the bit patterns as
needed.

Martin
 
A

Al Bowers

tuko said:
Hello kind people.

Can someone explain please the following code?

/* Create Storage Space For The Texture */
AUX_RGBImageRec *TextureImage[1]; /* Line 1*/
/* Set The Pointer To NULL */
memset(TextureImage,0,sizeof(void *)*1); /* Line 2*/

According to my knowledge in the first line
the TextureImage variable is declared as
an array of one pointer to AUX_RGBImageRec.

Here is my question.
I don't understand the second line at all.
Especially the sizeof(void *) *1 thing.
What does it mean?

The initialization of the array of Pointer
could be better like this
AUX_RGBImageRec *TextureImage[1] = {NULL};
Right? It has the same effect?
Possibly not have the same effect.
Your version will set the the array element to NULL.
The memset version is flawed. All-bits-zero
in a pointer object is not guaranteed to represent
a null pointer.

In addition, I fail to envision why the code declares
TextureImage as an array of 1. If there is only one
element you might as well declare it:
AUX_RGBImageRec *TextureImage = NULL;
One might declared an array of 1 with the intention of
playing allocation tricks, i.e. the last member of a
struct. This is covered in the faq. I prefer to declare:
AUX_RGBImageRec **TextureImage
and dynamically allocate the needed number of pointers.

Example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef char AUX_RGBImageRec; /* For an example */

int main(void)
{
AUX_RGBImageRec *pTextureImage = NULL;
AUX_RGBImageRec **ppTextureImage = NULL;
int i;
char *string[] = {"George Washington",
"Abe Lincoln",
"George Bush"};

pTextureImage = string[0];
printf("pTextureImage = \"%s\"\n\n",pTextureImage);

ppTextureImage = malloc((
sizeof *ppTextureImage)*(sizeof string/sizeof *string));
if(ppTextureImage)
{
puts("Some U,S. Presidents:");
for(i = 0;i < sizeof string/sizeof *string; i++)
{
ppTextureImage = string;
printf("ppTextureImage[%d] = \"%s\"\n",i,ppTextureImage);
}
free(ppTextureImage);
}
else puts("Memory allocation failure with ppTextureImage");
printf("sizeof(pTextureImage) = %u\nsizeof(void *) = %u\n",
sizeof pTextureImage, sizeof(void *));
return 0;
}

-
Al Bowers
Tampa, Fl USA
mailto: (e-mail address removed) (remove the x to send email)
http://www.geocities.com/abowers822/
 
C

Christian Bau

Hello kind people.

Can someone explain please the following code?

/* Create Storage Space For The Texture */
AUX_RGBImageRec *TextureImage[1]; /* Line 1*/
/* Set The Pointer To NULL */
memset(TextureImage,0,sizeof(void *)*1); /* Line 2*/

According to my knowledge in the first line
the TextureImage variable is declared as
an array of one pointer to AUX_RGBImageRec.

Here is my question.
I don't understand the second line at all.
Especially the sizeof(void *) *1 thing.
What does it mean?

The initialization of the array of Pointer
could be better like this
AUX_RGBImageRec *TextureImage[1] = {NULL};
Right? It has the same effect?

1. Yes.
2. It has the same effect as what the memset intends to do. The memset
is not portable and might go completely wrong, the corrected version
will always work. (void* doesn't necessarily have the same size as
AUX_RGBImageRec*, whatever an AUX_RGBImageRec is, and setting the
individual bytes in the representation of a pointer to zero doesn't
necessarily change the pointer to a null pointer as intended).
 
C

Christian Bau

"Stephen L. said:
Martin Dickopp wrote:

[ snip ]
Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.

Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!

When you pass a pointer to qsort, you cast it to void*. Same thing as
when you pass a short to a function that has a long argument.
 
C

Chris Torek

Possibly, yes.

When you pass a pointer to qsort, you cast it to void*. Same thing as
when you pass a short to a function that has a long argument.

Indeed. It might be worth expanding on this, though.

Suppose you have a qsort-callable function:

/* compare left- and right-side "zorg"s */
int zorgcompare(const void *l0, const void *r0) {
const struct zorg *l = l0; /* to sort an array of "zorg"s */
const struct zorg *r = r0; /* if array of ptrs, make these "**" */
... code to compare them ...
return whatever;
}

Now let us also suppose you have an unusual machine in which "struct
zorg *" is (say) four bytes long, but "void *" is 1048576 bytes
long (one megabyte). (Outrageous? Perhaps, but "Exaggeration of
System Parameters" is quite a good way of figuring out whether
something will break under stress. Apply a little ESP in your
daily life as an engineer or programmer!) When you call qsort()
to sort an array of "struct zorg" you do this:

struct zorg the_array[N];
... fill in the_array ...
/*
* The "void *" conversion happens even without the cast, and
* normally I suggest leaving it out, but it is here to show
* the explicit conversion. The value of n here is in [0..N),
* i.e., no more than the upper limit N.
*/
qsort((void *)&the_array[0], n, sizeof(struct zorg), zorgcompare);

Or, if zorgcompare() uses "const struct zorg **", you do this:

struct zorg *the_array[N];
... set up the_array, where i is in [0..n) and n <= N ...
... fill in the_array[0] (typically via the_array->field
rather than the_array[0].field) ...
qsort((void *)&the_array[0], n, sizeof(struct zorg *), zorgcompare);

In each case, you take a four-byte "struct zorg *" or "struct zorg **"
and convert it to one of these 1-megabyte-wide "void *"s.

Clearly, four bytes fit within a million.

Now qsort() does its thing, no doubt using "const char *" internally
because arithmetic is forbidden on "void *" pointers, on the bytes
that make up "the_array". As qsort() comes up with pointers pointing
to (each first byte of) the_array, it passes them, in "void *"
format -- one megabyte each -- to zorgcompare().

It is zorgcompare()'s job to extract the four *useful* bytes out
of the one-million, and use those to compare the desired "zorg"s.
Clearly, if the four bytes have a well-defined location within the
megabyte, the compiler will be able to pluck them out and use them.

In other words, it all works, despite the fact that, on this odd
machine, "void *" is ENORMOUS compared to other pointer types.

"But isn't this inefficient?" Yes, it is horrendously inefficient,
which is why real machines never use one-megabyte "void *" pointers.
You can trust the folks who write compilers to figure out some way
to make "void *" reasonably efficient on your machine. Obviously
"one megabyte" is not required, and chances are "four bytes" will
do the trick just fine, and parameter-passing will be efficient.

But if you have a sufficiently oddball machine, "void *" really
MIGHT be slightly less efficient than "struct zorg *" -- and if
your compiler writers are not supremely clever, AND you have this
weird kind of computer, AND "void *" parameter passing is noticeably
slow, AND all the parameter-passing involved in qsort() is making
your program run unacceptably slowly -- well, if all of these
amazing coincidences *all* turn out to be the case at once, *then*
you might want to use something other than qsort() and its
"void *"s. Until that proves to be the case, though, you might as
well just write the clearest, simplest code you can. Chances are,
any problems you run into will not have anything to do with
"void *" being inefficient.
 
J

Joe Wright

Christian said:
Martin Dickopp wrote:

[ snip ]

Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.

Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!


When you pass a pointer to qsort, you cast it to void*. Same thing as
when you pass a short to a function that has a long argument.

No. The whole point of C90 prototypes is to clue the compiler so
that it can do the conversions for you. You need not (and should
not) cast your arguments to functions to match the function's
parameters. The compiler will do it for you. math.h declares the
prototype..

double sqrt(double x);

...so that when you call 'sqrt(3);' with an int argument, the
compiler will figure it out and pass 3.0 instead. Really.
 
S

Stephen L.

Chris said:
Possibly, yes.
[ snip'd - example code about 1meg void pointer type and `qsort()' ]


....

"The same is true in C. While things may be big and small,
pointers come in one size (relatively small).[1]"
^^^^^^^^ ^^^^ ^^ ^^^ ^^^^

....


This is a sentence from the 5th paragraph after
illustration 13.1A from ->

http://www.oreilly.com/catalog/pcp3/chapter/ch13.html

If anyone believes that pointers to two different
types (even if one of the types is the `void' type)
are not the _same_ size; could be _different_ size(s)...

....well, don't make me come over there... :) :) :)

Really, though, the above link is _really_ good
reading to anyone interested in another viewpoint
on pointer to type(s) in the C language (I'm not
trying to insult anybody), and certainly authoritative.


Sincerely,

Stephen
 
M

Martin Dickopp

Stephen L. said:
Chris said:
Possibly, yes.
[ snip'd - example code about 1meg void pointer type and `qsort()' ]

"The same is true in C. While things may be big and small,
pointers come in one size (relatively small).[1]"
^^^^^^^^ ^^^^ ^^ ^^^ ^^^^
This is a sentence from the 5th paragraph after
illustration 13.1A from ->

http://www.oreilly.com/catalog/pcp3/chapter/ch13.html

The footnote [1] in the very same document (which you haven't quoted)
already clarifies that the statement isn't true.
If anyone believes that pointers to two different
types (even if one of the types is the `void' type)
are not the _same_ size; could be _different_ size(s)...

...well, don't make me come over there... :) :) :)

Don't know what you mean by that, but two pointers to different types
can certainly have different sizes.
Really, though, the above link is _really_ good reading

Well, after quickly skimming the document I found some things I don't
like stylistically (per-C89 definition of `main', return-statement
expression in parentheses), some things which are confusing (it is said
that `NULL' is defined in <locale.h>, but <stddef.h> isn't mentioned;
yet the example programs don't include <locale.h>), and some things
which are wrong (use of the word "illegal" where "invalid" is meant;
"pointers come in one size").
to anyone interested in another viewpoint
on pointer to type(s) in the C language (I'm not
trying to insult anybody), and certainly authoritative.

The only /authoritative/ document about the C language is the
/standard/.

Martin
 
S

Stephen L.

Martin said:
"The same is true in C. While things may be big and small,
pointers come in one size (relatively small).[1]"
^^^^^^^^ ^^^^ ^^ ^^^ ^^^^
This is a sentence from the 5th paragraph after
illustration 13.1A from ->

http://www.oreilly.com/catalog/pcp3/chapter/ch13.html

The footnote [1] in the very same document (which you haven't quoted)
already clarifies that the statement isn't true.

The footnote indicates that some platforms provide
non-standard extensions to the C language to overcome
deficiencies/quirks for that platform, and to make such
a platform more usable than it would be without the
extension(s). Why should I care, as a C programmer,
if a pointer needs to be NEAR or FAR? The C language
implementation on that platform should do that for me.
We're talking modern optimizing compilers, not some
implementation from the 80's with one foot still in
assembly language.

Also, we were talking specifically about the size of
pointers to two different _types_ being the same size,
even if one of the types was the `void' type.
Don't know what you mean by that, but two pointers to different types
can certainly have different sizes.

It's a Dilbert reference, meant in a friendly humorous way...
Well, after quickly skimming the document I found some things I don't
like stylistically (per-C89 definition of `main', return-statement
expression in parentheses), some things which are confusing (it is said
that `NULL' is defined in <locale.h>, but <stddef.h> isn't mentioned;
yet the example programs don't include <locale.h>), and some things
which are wrong (use of the word "illegal" where "invalid" is meant;
"pointers come in one size").

[ snips ]
The only /authoritative/ document about the C language is the
/standard/.

On that I agree, but even the "The C Programming Language"
had errata and style points that not everyone agreed with.
However, those issues had little impact on the significance
of the material presented in the book.

If the "standard" were all people needed to gain an
understanding of a language, publishers be'd out of
business in no time.


Just my point of view...

Stephen
 
C

Christian Bau

"Stephen L. said:
Chris said:
Possibly, yes.
[ snip'd - example code about 1meg void pointer type and `qsort()' ]


...

"The same is true in C. While things may be big and small,
pointers come in one size (relatively small).[1]"
^^^^^^^^ ^^^^ ^^ ^^^ ^^^^

...


This is a sentence from the 5th paragraph after
illustration 13.1A from ->

http://www.oreilly.com/catalog/pcp3/chapter/ch13.html

If anyone believes that pointers to two different
types (even if one of the types is the `void' type)
are not the _same_ size; could be _different_ size(s)...

...well, don't make me come over there... :) :) :)

Really, though, the above link is _really_ good
reading to anyone interested in another viewpoint
on pointer to type(s) in the C language (I'm not
trying to insult anybody), and certainly authoritative.

If you quoted it correctly, then it is certainly not authoritative.
 
M

Martin Dickopp

Stephen L. said:
Martin said:
"The same is true in C. While things may be big and small,
pointers come in one size (relatively small).[1]"
^^^^^^^^ ^^^^ ^^ ^^^ ^^^^
This is a sentence from the 5th paragraph after
illustration 13.1A from ->

http://www.oreilly.com/catalog/pcp3/chapter/ch13.html

The footnote [1] in the very same document (which you haven't quoted)
already clarifies that the statement isn't true.

The footnote indicates that some platforms provide
non-standard extensions to the C language to overcome
deficiencies/quirks for that platform, and to make such
a platform more usable than it would be without the
extension(s). Why should I care, as a C programmer,
if a pointer needs to be NEAR or FAR?

The footnote, as I understand it, gives an example of a platform where
even in a standard C implementation (i.e. no extensions), pointers of
two different sizes exist, namely 16 bit object pointers and 32 bit
function pointers or vice versa.
The C language implementation on that platform should do that for me.

It does, and to do so, it introduces object and function pointers of
different size.
Also, we were talking specifically about the size of
pointers to two different _types_ being the same size,
even if one of the types was the `void' type.

If the intention of the document is to claim that all object pointers
have the same size, then the document is wrong in this regard. The
standard simply doesn't require it.

Martin
 
K

Kevin Bagust

From the C99 Standard. Section 6.2.5.26

A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type. Similarly, pointers to
qualified or unqualified versions of compatible types shall have the same
representation and alignment requirements. All pointers to structure
types shall have the same representation and alignment requirements as
each other. All pointers to union types shall have the same
representation and alignment requirements as each other. Pointers to
other types need not to have the same representation and alignment
requirements.

This spells out that pointers to two different types need not be the same
size unless they are specified to be the same representation in the
preceding paragraph from the standard.

Kevin.
 
S

Stephen L.

Kevin said:
From the C99 Standard. Section 6.2.5.26

A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type. Similarly, pointers to
qualified or unqualified versions of compatible types shall have the same
representation and alignment requirements. All pointers to structure
types shall have the same representation and alignment requirements as
each other. All pointers to union types shall have the same
representation and alignment requirements as each other. Pointers to
other types need not to have the same representation and alignment
requirements.

This spells out that pointers to two different types need not be the same
size unless they are specified to be the same representation in the
preceding paragraph from the standard.

Kevin.

Yes, I _just_ found that reading my draft version
of the standard (there's more than just that paragraph).
The text doesn't actually use the word "size",
but you're making that connection and the phrase
"same representation", correct?

I always though of a `void *' as a generic pointer type,
however, the last sentence implies that there are
pointers which may not be contained in a `void *'.

Ignoring the alignment requirements parts of the text,
a function pointer comes to mind (on some architectures)
that may be represented differently. But what does
that mean? Does it mean its size is different from that
of a `char *', or does it mean its value is interpreted
_differently_ (maybe the components of the address
it represents are in a different order or scale then the
components for a `char *'). Or does it mean both.

I'm not entirely convinced that their intentional
use of the phrase "same representation" includes
a pointer's size as well. A pointer type of a
different _size_, well, would be a whole _new_
pointer type, I believe.

What I read is that the standard is trying to address
a pointer's access - read/write or execute.
A function pointer (having an `execute' attribute)
does not have to have the same representation as
a `char *' (having read/write access). The
standard doesn't have to differentiate between the
two, either, or warn if a function pointer is
dereferenced as a `char *'.

My understanding (aside from all of the alignment
language) is that pointers of the same attribute have
compatible access. All function pointers (containing
a valid function pointer) can be executed, all
"read/write" pointers can be read/wrote. But, if
you put a function pointer into a `char *' and
dereference it, the standard (IMHO) is saying
that it doesn't have to point to the binary
value of the start of your function. The pointer
value could be interpreted in a completely
different way as an access pointer. Likewise,
converting a `char *', pointing to valid
machine instructions, to a function *, and then
trying to execute that as a function, may
not work.


....But I'm still reading the standard...


Stephen
 
J

Jack Klein

Stephen L. said:
Martin Dickopp wrote:

[ snip ]
Secondly, `sizeof (void *)' (the size of a generic object pointer) need
not be the same as `sizeof (AUX_RGBImageRec *)' (the size of a pointer
to `AUX_RGBImageRec'), so the `memset' call doesn't even get the size
right.

Are you saying that `sizeof (AUX_RGBImageRec *) != sizeof (void *)'?

So, `AUX_RGBImageRec *' could _never_ be used inside the
compare function of `qsort(3C)' since its pointer size may
be different than the size of a `void *'?!!!

When you pass a pointer to qsort, you cast it to void*. Same thing as

When you pass a pointer to qsort(), you cast it to void* if you use a
cast operator to do so. If you have included <stdlib.h> or otherwise
have a correct prototype for qsort() in scope, the first pointer that
you pass to it is converted to "const void *", regardless of any cast
operator you might or might not explicitly code.
when you pass a short to a function that has a long argument.

When you pass a short value to a function whose prototype calls for a
value of type long, there is an implicit conversion of the short value
to a long. There is no cast unless you specifically code a cast.
 
J

Jack Klein

Yes, I _just_ found that reading my draft version
of the standard (there's more than just that paragraph).
The text doesn't actually use the word "size",
but you're making that connection and the phrase
"same representation", correct?

[snip]

Representation includes both the amount of memory occupied (i.e.,
size) and the interpretation of the bit pattern.

It is about time you stopped spouting nonsense and started paying
attention. You seem to have some experience with one or a few
compilers on one or a few particular platforms and thing you are
familiar with everything the C language encompasses.

There are platforms where pointers to void and the character types
actually do both occupy more space and contain more significant bits
than pointers to any other data types. This is quite frequently the
case on architectures where the minimum addressable machine word is
very wise, such as 32 or 64 bits.

Such platforms have two choices:

1. Define all of the integer types, even chars, to have 32 or 64 bits
(CHAR_BIT > 8). There are some perfectly conforming C implementations
that do this.

2. Automatically pack and un-pack characters from machine words which
hold multiple characters (rather like packed arrays in Pascal). All
other types occupy one or more full machine words. There are
perfectly conforming C implementations for these architectures as
well. In this case, pointers to char and therefore pointers to void
have more information than other pointer types. They not only must
contain the address of a machine word, as all other pointer types do,
but also some extra bits specifying which 8 bits out of the 32 or 64
are being referenced.

This happens to be true whether you like it or agree with it or not.

As for pointers to function, there is no conversion defined by the C
standard between pointers to any object type (including pointer to
void), and pointer to any kind of function. There is no requirement
or guarantee that there be any meaningful correspondence between them
at all.
 

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
474,142
Messages
2,570,820
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top