I have some stupids questions about void type and pointer to void.
Actually I've always known the answers but I wanted to find the
revelant parts in the C specs and fails.
The first one is about dereferencing a void pointer. It's just
forbidden but when reading 6.5.3.2 about indirection operators, I
can't find anything that states it.
The second one is about arithmetic on void *. I read section 6.5.6
about Additive operators but it doesn't state that arithmetic on void
* is forbidden. I thought that was the case since void * is a pointer
to an incomplete type.
The last question is about the section 6.2.5.26 which states: "A
pointer to void shall have the same representation and alignment
requirements as a pointer to a character type.". I'm not sure to
understand why the spec speaks about alignement requierements since a
pointer to void cannot be dereferenced.
Thanks for help.
I doubt that you mean to say this. I don't think you know how to use
english verbs correctly.
$.02
yes, probably this is better: "Actually I know the answers but I would
like to find the revelant parts in the C specs but have failed so
far."
Is this better ?
In C89, the most obvious port of call is 3.2.2.2 void (look for similar
wording in C99, which I don't have immediately to hand - it'll almost
certainly be identical): "The (nonexistent) value of a void expression
(an expression that has type void) shall not be used in any way". Since
dereferencing a void pointer would involve using a void value, this
paragraph forbids it.
>
> The second one is about arithmetic on void *. I read section 6.5.6
> about Additive operators but it doesn't state that arithmetic on void
> * is forbidden. I thought that was the case since void * is a pointer
> to an incomplete type.
In C89, the wording of the constraint is "either both operands shall
have arithmetic type, or one operand shall be a pointer to an object
type and the other shall have integral type". Since void is not an
object type, arithmetic on void * violates the constraint. Again, use
your viewer to search for similar (probably identical) wording in C99.
> The last question is about the section 6.2.5.26 which states: "A
> pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type.". I'm not sure to
> understand why the spec speaks about alignement requierements since a
> pointer to void cannot be dereferenced.
The Standard permits representations to vary. For example, it may be
that on a particular architecture all ints are on 16-byte boundaries
(say). On that architecture, in a pure binary representation the last
four bits would always be 0 for ints, so the architecture might have
some interesting or useful things for which it could use those bits.
(I'm no architecture guru, but I am given to understand that there are
architectures that work along these lines, although not necessarily
exactly as I have described). A void pointer has to be able to point at
any object, though, so it must be as flexible as a char pointer.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
>The first one is about dereferencing a void pointer. It's just
>forbidden but when reading 6.5.3.2 about indirection operators, I
>can't find anything that states it.
Void is an incomplete type, so it should be covered by a prohibition
on applying * to incomplete types. I can't see anything explicit
about this.
You might argue that it's forbidden becuase 6.5.3.2 says the
result would be of type void, and there are no objects of type
void.
The wording in 6.5.3.2 is odd; it says "If an invalid value has been
assigned to the pointer, the behaviour ... is undefined". Why
"assigned to"? It isn't necessarily a variable.
>The last question is about the section 6.2.5.26 which states: "A
>pointer to void shall have the same representation and alignment
>requirements as a pointer to a character type.". I'm not sure to
>understand why the spec speaks about alignement requierements since a
>pointer to void cannot be dereferenced.
Read the footnote.
-- Richard
--
Please remember to mention me / in tapes you leave behind.
> I have some stupids questions about void type and pointer to void.
There are no stupid questions.
> Actually I've always known the answers but I wanted to find the
> revelant parts in the C specs and fails.
>
> The first one is about dereferencing a void pointer. It's just
> forbidden but when reading 6.5.3.2 about indirection operators, I
> can't find anything that states it.
That's because it is not "forbidden". The C standard does not say
that anything is "forbidden", but a close match is those things that
are constraint violations (roughly speaking, compile-time errors) and
applying * to a void * is not one of these.
Some uses of * on void pointer are perfectly valid: &*vp is
well-defined for example.
Other clauses tell us that the result is of type void and that we
can't use the (non-existent) value of this type for any purpose at
all, which is enough for me. One can go further, in that void is not
an object type so one can argue that 6.5.3.2 p4 does not give a
meaning to * when applied to a void *. [The phrase "points to an
object" is not quite the same as "is a pointer to an object type that
points to an object" so, personally, I'd prefer a plain statement of
UB is that is what was intended.]
> The second one is about arithmetic on void *. I read section 6.5.6
> about Additive operators but it doesn't state that arithmetic on void
> * is forbidden. I thought that was the case since void * is a pointer
> to an incomplete type.
The clause you cite does forbid it; and for exactly the reason you
cite!. It is, in fact, a constraint violation because void is not an
object type:
Constraints
2 For addition, either both operands shall have arithmetic type, or
one operand shall be a pointer to an object type and the other
shall have integer type.
> The last question is about the section 6.2.5.26 which states: "A
> pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type.". I'm not sure to
> understand why the spec speaks about alignement requierements since a
> pointer to void cannot be dereferenced.
I am not sure the alignment part has any effect (the representation
part is important). I suspect the standard would be the same if the
words "and alignment requirements" were deleted. The standard does
not define exactly what "having the same representation" means, so the
extra words do help to make it certain that a void * can never require
more or less alignment than a char *.
--
Ben.
Actually, there are very many stupid questions. But these weren't three
of them.
<snip>
Yes. If it's to be english, then you'll need to divest yourself
somewhat of the initial adverb, but if it's failing with C, then it's a
language we all know. :)
Cheers,
--
6.5.3.2p4 specifies what happens when dereferencing a
pointer "to a function" or "to an object." A void* obviously
can't do the first. What you're probably missing is that it
also can't do the second, because of 6.2.5p1: "[...] Types are
partitioned into object types [...], function types [...], and
incomplete types [...]" A void* is a pointer to an incomplete
type, not a pointer to an object type, so the language of
6.5.3.2p4 doesn't apply. The outcome of a dereference is
undefined not because the Standard says so explicitly, but
because it doesn't say anything to define it (see 4p2).
> The second one is about arithmetic on void *. I read section 6.5.6
> about Additive operators but it doesn't state that arithmetic on void
> * is forbidden. I thought that was the case since void * is a pointer
> to an incomplete type.
You're right, and the reasoning is the same as before.
6.5.6p2 requires that the pointer be "to an object type," which
leaves out incomplete types. (This is in a Constraints section,
so the implementation must diagnose the attempt).
> The last question is about the section 6.2.5.26 which states: "A
> pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type.". I'm not sure to
> understand why the spec speaks about alignement requierements since a
> pointer to void cannot be dereferenced.
It's speaking of the alignment requirements of the pointer
itself, not of the thing pointed to. A void* variable is like
any other (non-bit-field) variable: double, int**, short, or
whatever, and as such may have some kind of alignment requirement.
The Standard says that the alignment requirement for a void* is
the same as that for a char* (presumably because char* was "the
generic pointer" before void* was introduced to the language, and
the 1989 Standard didn't want to mess up existing code unduly).
--
Eric Sosman
eso...@ieee-dot-org.invalid
> On 2/2/2010 4:34 AM, Francis Moreau wrote:
>> Hello,
>>
>> I have some stupids questions about void type and pointer to void.
>>
>> Actually I've always known the answers but I wanted to find the
>> revelant parts in the C specs and fails.
>>
>> The first one is about dereferencing a void pointer. It's just
>> forbidden but when reading 6.5.3.2 about indirection operators, I
>> can't find anything that states it.
>
> 6.5.3.2p4 specifies what happens when dereferencing a
> pointer "to a function" or "to an object." A void* obviously
> can't do the first. What you're probably missing is that it
> also can't do the second, because of 6.2.5p1: "[...] Types are
> partitioned into object types [...], function types [...], and
> incomplete types [...]" A void* is a pointer to an incomplete
> type, not a pointer to an object type, so the language of
> 6.5.3.2p4 doesn't apply.
I'm not entirely persuaded by this because the phrase "points to an
object" is not as precise as I'd like. For example in 6.2.4 p2 we
read:
"The value of a pointer becomes indeterminate when the object it
points to reaches the end of its lifetime."
This is surely meant to cover a void * pointing to an object, but if
we take your strict reading of pointing to an object a void * can't
point to an object. I am pretty sure that your reading of 6.5.3.2 p4
is the one that was intended, but I'd prefer it to be a little more
explicit.
<snip>
--
Ben.
An excellent contribution to the thread.
--
Ted DeLoggio
> Ben Bacarisse wrote:
>> Francis Moreau <franci...@gmail.com> writes:
>>
>>> I have some stupids questions about void type and pointer to void.
>>
>> There are no stupid questions.
>
> Actually, there are very many stupid questions. But these weren't
> three of them.
Is "are there any stupid questions?" a stupid question? How about that one?
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
No.
> How about that one?
No. But here's an example of a stupid question: "Will the trolls ever
get a clue?"
You shouldn't be talking, frankie-boy, especially since you don't know
how to capitalise "English".
Richard
Ah yes, this is what I was missing: an incomplete type is not the same
as an object type.
>
> > The second one is about arithmetic on void *. I read section 6.5.6
> > about Additive operators but it doesn't state that arithmetic on void
> > * is forbidden. I thought that was the case since void * is a pointer
> > to an incomplete type.
>
> You're right, and the reasoning is the same as before.
> 6.5.6p2 requires that the pointer be "to an object type," which
> leaves out incomplete types.
Agreed.
> (This is in a Constraints section,
> so the implementation must diagnose the attempt).
Strangely enough, gcc doesn't:
int main(void)
{
void *p = (void *)0;
p = p + 1;
return 0;
}
Compiling this with: 'gcc -Wall main.c', doesn't produce any warnings/
errors.
>
> > The last question is about the section 6.2.5.26 which states: "A
> > pointer to void shall have the same representation and alignment
> > requirements as a pointer to a character type.". I'm not sure to
> > understand why the spec speaks about alignement requierements since a
> > pointer to void cannot be dereferenced.
>
> It's speaking of the alignment requirements of the pointer
> itself, not of the thing pointed to. A void* variable is like
> any other (non-bit-field) variable: double, int**, short, or
> whatever, and as such may have some kind of alignment requirement.
> The Standard says that the alignment requirement for a void* is
> the same as that for a char* (presumably because char* was "the
> generic pointer" before void* was introduced to the language, and
> the 1989 Standard didn't want to mess up existing code unduly).
Again thank you for explanations.
I agree that some others sections may be confusing, specially if you
miss 6.2.5p1 as I did.
Thanks all for your help.
Right, "gcc -Wall" is not a conforming C compiler.
Adding the "-pedantic" option causes it to warn about the above code:
warning: pointer of type `void *' used in arithmetic
A non-fatal warning is a valid response to a constraint violation.
(I don't think "-pedantic" by itself is sufficient to cause gcc to
become a conforming C compiler.)
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
"Why are you so dim?" is rhetorical, maybe stupid.
"What is infinity?" is interrogative, a question, and not stupid.
--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."
> The last question is about the section 6.2.5.26 which states: "A
> pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type.". I'm not sure to
> understand why the spec speaks about alignement requierements since a
> pointer to void cannot be dereferenced.
Note that alignment requirements mentioned here are for
the actual _pointers_, not for what's being pointed to.
A (char*) variable and a (void*) variable have the same
alignment requirement (which is unrelated to the alignment
of (char)).
> On 2/2/2010 4:34 AM, Francis Moreau wrote:
>> Hello,
>>
>> I have some stupids questions about void type and pointer to void.
>>
>> Actually I've always known the answers but I wanted to find the
>> revelant parts in the C specs and fails.
>>
>> The first one is about dereferencing a void pointer. It's just
>> forbidden but when reading 6.5.3.2 about indirection operators, I
>> can't find anything that states it.
>
> 6.5.3.2p4 specifies what happens when dereferencing a
> pointer "to a function" or "to an object." A void* obviously
> can't do the first. What you're probably missing is that it
> also can't do the second, because of 6.2.5p1: "[...] Types are
> partitioned into object types [...], function types [...], and
> incomplete types [...]" A void* is a pointer to an incomplete
> type, not a pointer to an object type, so the language of
> 6.5.3.2p4 doesn't apply.
I believe this interpretation is a misreading. The Standard means
what it says, if the pointer "points to an object" is talking about
where the pointer points, not what type of pointer it is. And this
is there to rule out null pointers, which don't point to an object.
Pointers to incomplete types (and that aren't null pointers, or
point one past the end of an array) still point to objects.
Why then is it undefined behavior? Pray read on...
> The outcome of a dereference is
> undefined not because the Standard says so explicitly, but
> because it doesn't say anything to define it (see 4p2).
Indirecting through a pointer to an incomplete type (not just (void))
is undefined behavior because 6.3.2.1p2 says so explicitly:
Except when it is the operand of the sizeof operator, the unary
& operator, the ++ operator, the -- operator, or the left
operand of the . operator or an assignment operator, an lvalue
that does not have array type is converted to the value stored
in the designated object (and is no longer an lvalue). If the
lvalue has qualified type, the value has the unqualified version
of the type of the lvalue; otherwise, the value has the type of
the lvalue. If the lvalue has an incomplete type and does not
have array type, the behavior is undefined.
> Nick wrote:
>> Richard Heathfield <r...@see.sig.invalid> writes:
>>
>>> Ben Bacarisse wrote:
>>>> Francis Moreau <franci...@gmail.com> writes:
>>>>
>>>>> I have some stupids questions about void type and pointer to void.
>>>> There are no stupid questions.
>>> Actually, there are very many stupid questions. But these weren't
>>> three of them.
>>
>> Is "are there any stupid questions?" a stupid question?
>
> No.
>
>> How about that one?
>
> No. But here's an example of a stupid question: "Will the trolls ever
> get a clue?"
How about whether you will ever get a clue? I know
some people think that's a stupid question.
Stop being such a shit stirrer.
> The first one is about dereferencing a void pointer. It's just
> forbidden but when reading 6.5.3.2 about indirection operators, I
> can't find anything that states it.
My answer to this question is given in a response to
Eric Sosman's posting.
I'm one of them.
> Stop being such a shit stirrer.
I'm impressed by your ability to jump to conclusions.
[ much snippage ]
>
> I believe this interpretation is a misreading. The Standard means
> what it says, if the pointer "points to an object" is talking about
> where the pointer points, not what type of pointer it is.
Only in the case of void*. All valid pointers to objects have type.
> And this
> is there to rule out null pointers, which don't point to an object.
> Pointers to incomplete types (and that aren't null pointers, or
> point one past the end of an array) still point to objects.
"Pointers to incomplete types" points to what objects? An object being a
region of storage etc..
I know that my English sucks (as someone pointed out) but I'm not
convinced about what you stated:
Here's the beginning of 6.2.5p1:
The meaning of a value stored in an object or returned by a
function is determined by the type of the expression used to
access it. Types are partitioned into...
Why is the spec so hard to read ?!
[snip]
What is the connection between your quote and the topic? As I read
it, the issue is whether a void * can be said to "point to an object"
despite the undisputed fact that a void * is a pointer to an
incomplete type not a pointer to an object type.
I.e. is it reasonable to say that after
int i = 42;
void *vp = &i;
vp does or does not point to i? I can see both sides, but I come down
with Tim on this one. My reason is that the standard uses the phrase
loosely somewhere else; specifically "6.2.4 Storage durations of
objects" paragraph 2:
2 The lifetime of an object is the portion of program execution
during which storage is guaranteed to be reserved for it. An
object exists, has a constant address and retains its last-stored
value throughout its lifetime. If an object is referred to outside
of its lifetime, the behavior is undefined. The value of a pointer
becomes indeterminate when the object it points to reaches the end
of its lifetime.
This clause would not apply to vp in either of these two situations:
void *vp; { int i; vp = &i; }; /* is vp indeterminate? */
or
void *vp = malloc(1); free(vp); /* is vp indeterminate? */
if the phrase were not to taken rather loosely. I am pretty sure that
in both these cases the intent was that 6.2.4 p2 would apply. Such
arguments are not strong, I agree, but other than "plain reading" I
have nothing better right now.
In summary, the distinction between a pointer that "points to an
object" and one that is of "pointer to object type" is fussy but
significant here.
--
Ben.
> Tim Rentsch wrote:
>
> [ much snippage ]
>>
>> I believe this interpretation is a misreading. The Standard means
>> what it says, if the pointer "points to an object" is talking about
>> where the pointer points, not what type of pointer it is.
>
> Only in the case of void*. All valid pointers to objects have type.
Surely you realize that (void) is a type. A (void*) pointer
points to something of type (void). The type (void) is
unusual in several respects, but it is still a type.
>> And this
>> is there to rule out null pointers, which don't point to an object.
>> Pointers to incomplete types (and that aren't null pointers, or
>> point one past the end of an array) still point to objects.
>
> "Pointers to incomplete types" points to what objects? An object being
> a region of storage etc..
Here is the last sentence of 6.2.5p1:
Types are partitioned into object types (types that fully
describe objects), function types (types that describe
functions), and incomplete types (types that describe objects
but lack information needed to determine their sizes).
Note the last part. Incomplete types still describe objects. Pointers
to incomplete types still point to objects, it just isn't known how
big the objects are.
I'm not sure if the question posed is meant as rhetorical or
to be directed to me, but in either case I'd like to respond
to the "not convinced" statement.
First here's the rest of that last sentence from 6.2.5p1:
Types are partitioned into object types (types that fully
describe objects), function types (types that describe
functions), and incomplete types (types that describe objects
but lack information needed to determine their sizes).
Note that incomplete types still describe objects.
Talking about pointers, in the Standard commonly uses the phrases
"pointer to [X]" and "points to [Y]", for different X's and Y's. The
phrase "pointer to [X]" sometimes is talking about the type of what's
being pointed to, and sometimes is talking about what is being pointed
to rather than its type. As far as I am aware (having checked through
scads of references), the two kinds of usage are consistent when
talking about "objects". More specifically, if "object" is used as a
noun, the phrase is talking about _what's_ being pointed at, but if
the phrase is talking about the _type_ of what's being pointed at,
"object" will be used as an adjective (modifying "type").
For "points to ...", as far as I am aware this phrase (when discussing
a pointer) is always talking about _what_ the pointer is pointing
at, not what type of thing it's pointing at. There is one case
where "points to ..." is talking about the type of the thing pointed
to, but the item under discussion in that case is a type name (T), not
a pointer.
Of course, I may have missed some uses of these phrases; still I did
look at quite a few. If you find any that don't agree with the above
descriptions, I definitely would like to hear about them.
Also, notice a sentence in the same section (specifically in 6.5.3.2p1
(talking about the unary & operator):
The operand of the unary & operator shall be either a function
designator, the result of a [] or unary * operator, or an lvalue
that designates an object that is not a bit-field and is not
declared with the register storage-class specifier.
Notice the "an object" phrase. This constraint is talking about
what is being designated, not about whether the operand has object type
or not. We know that because this code
int some_array[];
int (*some_array_address)[] = &some_array;
is legal, and the operand 'some_array' has incomplete type. So
that is another confirming instance when "an object", used as a
noun rather than an adjective modifying "type", means 'what is
being referred to' and not 'what kind of type it has'.
Is that more convincing now?
> Types are partitioned into object types (types that fully
> describe objects), function types (types that describe
> functions), and incomplete types (types that describe objects
> but lack information needed to determine their sizes).
>Note the last part. Incomplete types still describe objects. Pointers
>to incomplete types still point to objects, it just isn't known how
>big the objects are.
Are you saying that because void is an incomplete type, void *
pointers point to objects of unknown size? They certainly doesn't
point to objects of type void, because there aren't any.
> In article <kfn636a...@x-alumni2.alumni.caltech.edu>,
> Tim Rentsch <t...@alumni.caltech.edu> wrote:
>
>> Types are partitioned into object types (types that fully
>> describe objects), function types (types that describe
>> functions), and incomplete types (types that describe objects
>> but lack information needed to determine their sizes).
>
>>Note the last part. Incomplete types still describe objects. Pointers
>>to incomplete types still point to objects, it just isn't known how
>>big the objects are.
>
> Are you saying that because void is an incomplete type, void *
> pointers point to objects of unknown size?
Yes.
> They certainly doesn't
> point to objects of type void, because there aren't any.
There aren't any objects of type (int[]) either, but
pointers to incomplete arrays still point to objects.
The type (void) is unusual in that it means, in a sense,
"any type" or "some undetermined type". It's also unusual
in that, used by itself (ie, not as part of a pointer type)
it means something different than it does in conjunction
with pointerness -- namely, (void) approximately means
"valueless" or "disregard the value, if any". This last
sense resembles the "any type" of a target of (void *),
because any value may converted to a "value" of type (void).
So in some sense all objects are objects of type (void),
in addition to whatever other type(s) they may be.
> Francis Moreau <franci...@gmail.com> writes:
>> On Feb 2, 2:07 pm, Eric Sosman <esos...@ieee-dot-org.invalid>
>> wrote:
<snip>
> (I don't think "-pedantic" by itself is sufficient to cause gcc
> to become a conforming C compiler.)
You are right. Using the `-ansi' or `-std=...' switches are needed
to disable the GNU extensions.
--
"Don't worry about efficiency until you've attained correctness."
~ Eric Sosman, comp.lang.c