Email List: Xaustin-group-lX
[All Lists]

Re: [1003.1(2008)/Issue 7 0000074]: Pointer Types Problem

To: "Schwarz, Konrad" <konrad.schwarz@xxxxxxxxxxx>
Subject: Re: [1003.1(2008)/Issue 7 0000074]: Pointer Types Problem
From: Wojtek Lerch <wojtek@xxxxxxx>
Date: Thu, 02 Jul 2009 17:15:18 -0400
Cc: Geoff Clare <gwc@xxxxxxxxxxxxx>, austin-group-l@xxxxxxxxxxxxx
References: <e26e5335cda9d0dfe49395e6115066fe@austingroupbugs.net> <1730938080F74546ACC51CB65BA00565@ott.qnx.com> <20090702094404.GA28393@squonk.masqnet> <4A4CC239.2040603@qnx.com> <5030E566C603DA449D6B4C060CE529B73A8F37@MCHP7RDA.ww002.siemens.net>
Schwarz, Konrad wrote:
I think it would be best to stick as closely to the language of the C
standard as possible.
Agreed.

I.e., using ISO/IEC 9899:1999 (E), section 6.3.2.2, paragraph 1 as a
guide:

	A pointer to <b>void</b> may be converted to or from a pointer
to any function type.
You would want to allow converting *any* void pointers to function pointers? I don't think that's necessary. I think it's better to let it be undefined behaviour, except for void pointers that are converted pointers to function. That would make it consistent with conversions from void* to other pointer types in standard C -- they're undefined unless you have made sure that you're not violating any alignment requirements. (And since alignment requirements are unspecified, it's hard to satisfy them other than by ensuring that your void pointer indeed points to an object of the correct type. Or was returned by malloc().)

	A pointer to any function type may be converted to a pointer to
<b>void</b> and back
	again, the result shall compare equal to the original pointer.
Right.   It should not be symmetrical.

This just replaces "pointer to any incomplete or object type" with
"pointer to any function type"
in paragraph 1.


I don't think it's a good idea to introduce unusual restrictions on what the void* pointer can be converted to. Can I convert it to a "void const*"? What about a "void *const"? Why would it need to be undefined behaviour to convert it to a char*, even though standard C intends to allow converting any valid void* pointer to char*?

I think these questions are largely answered by paragraph 2 of the
section quoted above:

	For any qualifier q, a pointer to a non-q-qualified type may be
converted to a pointer to
	the q-qualified version of the type; the values stored in the
original and converted pointers
	shall compare equal.
I don't think it's clear that that paragraph applies. Keep in mind that we're talking about programs that have invoked undefined behaviour according to the C standard (by converting a function pointer to a void pointer). This new kind of void* values that POSIX is trying to introduce does not exist in standard C; if POSIX specifically says that the behaviour is undefined if such a value is converted to a pointer to an object or an incomplete type, I would tend to interpret that as overriding what C says about conversions of normal pointers -- not the other way around.

Also, a few details are missing from the wording in question:

* Do these conversion work with null pointers? Are they guaranteed to turn null pointers into null pointers? (If not, then one needs to test the result of dlsym() before converting it to a function pointer, rather than after.)

This is answered by paragraphs 3 and 4:
...
	Conversion of a null pointer to another pointer type yields a
null pointer of that type.
OK, but still, it's not obvious to me that this necessarily applies to conversions that have undefined behaviour in standard C.

* Is it possible for the converted void* pointer to compare equal to the address to some object? (It can happen on hardware with separate address spaces for code and data -- does POSIX want to support such hardware?)

I think POSIX should leave these areas unspecified---what does
specifying these details gain POSIX?  Thus add to the above:
Normally a void* pointer can be compared to another void* pointer; if you make it undefined behaviour for some valid pointers, you'll be introducing an inconsistency that people will tend to forget about. My feeling is that it would be better to allow comparing but discourage it by saying that the result is unspecified.

(I would still prefer to say that it may accidentally happen to compare equal to some object pointers, because that's consistent with how C says that a pointer to object may accidentally compare equal to a pointer past the end of some unrelated array. But I could live with simply "unspecified", even though I don't like the idea of it returning any value other than 0 or 1, or the idea that it might return different values when you compare the same two pointers twice.)

	If a pointer to any function type, converted to a pointer to
<b>void</b>,
	is used for any purpose other than conversion back to a pointer
to a
	function or comparison with a null pointer, the behavior is
undefined.
Comparison with a null pointer, or specifically with a null pointer constant?

Can't it be used in an assignment? In a compound literal? Passed to a function? Returned from a function? Used to initialize a variable? Converted to void? To _Bool? To another function pointer stored in a void*?

In general, it would be good idea to consult Clive D.W. Feather on this.
Agreed.

<Prev in Thread] Current Thread [Next in Thread>