Topic: Can pointer to function be explicitly converted to void* ?


Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 03:36:05 GMT
Raw View
MikeAlpha@NoSpam_csi.com (Martin Aupperle) writes:

|>  On Sun,  8 Oct 2000 23:17:19 GMT, James Kuyper <kuyper@wizard.net>
|>  wrote:

|>  >Because on many platforms, the simplest way to implement each type
|>  >of pointer is one that doesn't allow such conversions. For
|>  >instance, if the code and the data are kept entirely separate (a
|>  >good idea, in general), then code pointers might be shorter than
|>  >data pointers (or vice versa, though that's less common, in my
|>  >experience).

|>  Can You give an example of an arechitecture where there are different
|>  sizes of data and function poiners?

Everyone will mention the Intel architecture -- not exactly rare.  There
is also the NSC 32000.  And of course, word addressed machines will
almost always have a char*/void* bigger than any other pointer type.

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 03:39:09 GMT
Raw View
MikeAlpha@NoSpam_csi.com (Martin Aupperle) writes:

|>  On Sun, 10 Sep 2000 00:27:56 GMT, Jack Klein <jackklein@att.net>
|>  wrote:

|>  >It is not standard.  C had two types of pointers: to objects and
|>  >functions.  C++ extends this by adding a third type, pointer to
|>  >non-standard member function.  There is no conversion between any
|>  >of the three types in C++, or either of the two types in C.

|>  I always thought that there is no difference between an address of a
|>  function and an address of a variable. It should be possible to
|>  convert both types to void* and back to the original type without
|>  problems. Why does the difference exist?

Because the two types of pointers may be incompatible.  When the C
standard was being written, 16 bit Intel architecture was widespread.
And on 16 bit Intel architecture, one of the compilation models used 16
bit data pointers and 32 bit function pointers.

Generally, from my compiler experience, you have to deal with four sizes
of pointers: char*, other_data*, function* and label*.  (C/C++ has no
support for the latter, but they occur in the internal implementation of
a switch, for example.)  I've never seen a machine where all four were
different, but even with two sizes, which one was different will vary.

Finally, pointers to members aren't pointers, and are unrelated to
pointers.  So one would expect their sizes to vary as well.  (And of
course, there is also nothing which guarantees that a pointer to data
member have the same size as a pointer to member function -- because
data can't be virtual, in fact, they rarely do.)

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: 2000/10/09
Raw View
Martin Aupperle wrote:
>
> On Sun,  8 Oct 2000 23:17:19 GMT, James Kuyper <kuyper@wizard.net>
> wrote:
>
> >Because on many platforms, the simplest way to implement each type of
> >pointer is one that doesn't allow such conversions. For instance, if the
> >code and the data are kept entirely separate (a good idea, in general),
> >then code pointers might be shorter than data pointers (or vice versa,
> >though that's less common, in my experience).
> >
> Can You give an example of an arechitecture where there are different
> sizes of data and function poiners?

Sure: Intel 80x86 family, among the most common platforms in the world.
Back when I was programming for DOS, memory addresses took the form of a
2 byte segment and a 2 byte offset. The physical location in memory was
given (I kid you not!) by 16*segment+offset, allowing access to 1MB of
memory. How could anyone ever need more than that! :-) Later versions
did something more reasonable, but I ceased programming for DOS about
the same time those alternatives started coming into fashion, so I'm not
very familiar with them. I believe at least some of those alternatives
still retained the segment/offset distinction; they just mapped it to
physical memory locations in a more reasonable manner.

Most compilers for PC's that I was familiar with provided one or more of
two kinds of pointers. Rar pointers were four bytes and contained both
the segment and the offset, so they could address any memory location on
the machine. Near pointers were two bytes and just contained the offset,
and used default values for the segment, when needed. The net result was
that a near pointer was restricted to a 64K range, and near objects
(objects where &x returned a near pointer) were restricted to a total
combined size of 64K. A well written compiler working on code with near
pointers would load the default segment values into the appropriate
segment registers near the start of a program, and would almost never
have to reload them. Near pointers took up significantly less memory
space and less processing time than far pointers.

If you declared a pointer without the 'near' or 'far' keywords (which
were an extension to C, which incidentally violated the namespace
reserved for users), they would default to a particular type of pointer.
That way you could actually compile strictly conforming code that never
used 'near' or 'far'.

Since there were different segment registers for code segments and for
data segments, most compilers provided options making either 'near' or
'far' the default pointer type for category separately. You could set
different defaults on function pointers and on data pointers. If I
remember correctly:

 Model |Data |Code
 ========|=======|====
 Small |near |near
 Compact |far |near
 Large |far |far

There was a model where the default was far function pointers and near
data pointers, but I never had any use for it, so I can't remember what
it's name was.
Implementations where pointers to different types have different sizes
are not uncommon, but the 80x86 family is the only one I'm personally
familiar with.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 2000/10/09
Raw View
In article <39dc9170.154066878@news.nikoma.de>, Martin Aupperle
<MikeAlpha@NoSpam_csi.com> writes
>I always thought that there is no difference between an address of a
>function and  an address of a variable. It should be possible to
>convert both types to void* and back to the original type without
>problems. Why does the difference exist?

More to the point, why do you think it should not? Why should void* have
to be large enough to store a function pointer on systems where function
pointers are larger (often twice the size) than data pointers?


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 2000/10/10
Raw View
In article <39e1717d.488102@news.nikoma.de>, Martin Aupperle
<MikeAlpha@NoSpam_csi.com> writes
>Can You give an example of an arechitecture where there are different
>sizes of data and function poiners?

MSDOS medium and compact memory models

>

Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: MikeAlpha@NoSpam_csi.com (Martin Aupperle)
Date: 2000/10/08
Raw View
On Sun, 10 Sep 2000 00:27:56 GMT, Jack Klein <jackklein@att.net>
wrote:

>
>It is not standard.  C had two types of pointers: to objects and
>functions.  C++ extends this by adding a third type, pointer to
>non-standard member function.  There is no conversion between any of
>the three types in C++, or either of the two types in C.
>
I always thought that there is no difference between an address of a
function and  an address of a variable. It should be possible to
convert both types to void* and back to the original type without
problems. Why does the difference exist?

Martin

------------------------------------------------
Martin Aupperle
MikeAlpha@NoSpam_csi.com
(remove NoSpam_)
------------------------------------------------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/10/08
Raw View
Martin Aupperle wrote:
>
> On Sun, 10 Sep 2000 00:27:56 GMT, Jack Klein <jackklein@att.net>
> wrote:
>
> >
> >It is not standard.  C had two types of pointers: to objects and
> >functions.  C++ extends this by adding a third type, pointer to
> >non-standard member function.  There is no conversion between any of
> >the three types in C++, or either of the two types in C.
> >
> I always thought that there is no difference between an address of a
> function and  an address of a variable. It should be possible to
> convert both types to void* and back to the original type without
> problems. Why does the difference exist?

Because on many platforms, the simplest way to implement each type of
pointer is one that doesn't allow such conversions. For instance, if the
code and the data are kept entirely separate (a good idea, in general),
then code pointers might be shorter than data pointers (or vice versa,
though that's less common, in my experience).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: MikeAlpha@NoSpam_csi.com (Martin Aupperle)
Date: 2000/10/09
Raw View
On Sun,  8 Oct 2000 23:17:19 GMT, James Kuyper <kuyper@wizard.net>
wrote:

>Because on many platforms, the simplest way to implement each type of
>pointer is one that doesn't allow such conversions. For instance, if the
>code and the data are kept entirely separate (a good idea, in general),
>then code pointers might be shorter than data pointers (or vice versa,
>though that's less common, in my experience).
>
Can You give an example of an arechitecture where there are different
sizes of data and function poiners?


------------------------------------------------
Martin Aupperle
MikeAlpha@NoSpam_csi.com
(remove NoSpam_)
------------------------------------------------

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kgw-zamboni-news@stiscan.com (Ken Walter)
Date: 2000/10/09
Raw View
On Sun, 9 Oct 2000 14:29:53, MikeAlpha@NoSpam_csi.com (Martin
Aupperle) wrote:

#>
#Can You give an example of an arechitecture where there are different
#sizes of data and function poiners?
#
#
The old x86 DOS where either pointer space could be near(16bit) or
far.



Ken Walter

Remove -zamboni to reply
All the above is hearsay and the opinion of no one in particular

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/10/09
Raw View

Martin Aupperle wrote
>
> I always thought that there is no difference between an address of a
> function and  an address of a variable. It should be possible to
> convert both types to void* and back to the original type without
> problems. Why does the difference exist?
>
You're incorrect.  The major reason for the distinction is that many
architectures treat functions (instructions) as a different type of
memory from data.   A void* is only required to be able to hold any
OBJECT (data) pointer.  There is however, no generic, pointer to
instructions class, however, you can cast to just about any and
back with impunity.

The issue is that void* may be a different size than void(*)().

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/09/14
Raw View
Jack Klein wrote:
>> It is not standard.  C had two types of pointers: to objects and
>> functions.  C++ extends this by adding a third type, pointer to
>> non-static member function.

Ron Natalie wrote:
> Of course, it's bogus what will happens, but you can always bounce
> through a "suitabley large" int with a reinterpret_cast.

Only if your implementation has a "suitably large" integer type.
IBM AS/400 C had 128-bit pointers, but I don't believe it had any
128-bit integer type.

C99 provides a suitable integer type, called 'intptr_t'.

On the other hand, it would probably be safe to say that most C/C++
compilers support converting between data pointers and function
pointers, since they are commonly the same size.  Member function
pointers probably aren't as commonly convertible.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/09/15
Raw View
David R Tribble <david@tribble.com> writes:

 >Jack Klein wrote:
 >>> It is not standard.  C had two types of pointers: to objects and
 >>> functions.  C++ extends this by adding a third type, pointer to
 >>> non-static member function.
 >
 >Ron Natalie wrote:
 >> Of course, it's bogus what will happens, but you can always bounce
 >> through a "suitabley large" int with a reinterpret_cast.
 >
 >Only if your implementation has a "suitably large" integer type.
 >IBM AS/400 C had 128-bit pointers, but I don't believe it had any
 >128-bit integer type.
 >
 >C99 provides a suitable integer type, called 'intptr_t'.

The `intptr_t' type in C99 is optional.
Implementations are not required to provide such a type.
C99 just provides a standard name for such a type,
in case it does exist.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/09/15
Raw View
Fergus Henderson wrote:
..
> The `intptr_t' type in C99 is optional.
> Implementations are not required to provide such a type.
> C99 just provides a standard name for such a type,
> in case it does exist.

It also provides several macros must be defined if and only if the type
is supported, which allows #ifdef'ing your code based on those macros.
That is a very welcome improvement over the previous standard.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Gil Shafriri" <gilsh@microsoft.com>
Date: Sat, 9 Sep 2000 13:42:54 GMT
Raw View
The following code that explicitly convert pointer to function to void*
compiles OK on vc6.

typedef int (*func_ptr_t)();

func_ptr_t func_ptr=0;

void* p = reinterpret_cast<void*>(func_ptr);

I was thinking that explicit conversion from pointer to function to pointer
to data is not allowed. Looking at the standard     I could not find that it
is allowed.

Is it compiler bug or did I miss anything in reading the standard ?

Thanks,

Gil



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Ron Natalie <ron@sensor.com>
Date: Mon, 11 Sep 2000 23:08:16 GMT
Raw View

Jack Klein wrote:
>
>
> It is not standard.  C had two types of pointers: to objects and
> functions.  C++ extends this by adding a third type, pointer to
> non-standard member function.

Pointer to non-standard member function?  Freudian slip?
Pointer to non-static member function?


Of course, it's bogus what will happens, but you can always bounce through
a "suitabley large" int with a reinterpret_cast.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jack Klein <jackklein@att.net>
Date: Sun, 10 Sep 2000 00:27:56 GMT
Raw View
On Sat,  9 Sep 2000 13:42:54 GMT, "Gil Shafriri" <gilsh@microsoft.com>
wrote in comp.std.c++:

> The following code that explicitly convert pointer to function to void*
> compiles OK on vc6.
>
> typedef int (*func_ptr_t)();
>
> func_ptr_t func_ptr=0;
>
> void* p = reinterpret_cast<void*>(func_ptr);
>
> I was thinking that explicit conversion from pointer to function to pointer
> to data is not allowed. Looking at the standard ? I could not find that it
> is allowed.
>
> Is it compiler bug or did I miss anything in reading the standard ?
>
> Thanks,
>
> Gil

It is not standard.  C had two types of pointers: to objects and
functions.  C++ extends this by adding a third type, pointer to
non-standard member function.  There is no conversion between any of
the three types in C++, or either of the two types in C.

On the other hand, many operating systems and utilities were developed
before the existence of C++ or the standardization of C and took
advantage of what they "knew" about the underlying representation of
pointers to stuff everything into a single pointer to void, or a
single signed or unsigned int before the type pointer to void existed.

There are quite a few OS features in most UNIX variants and in
Windows, and probably other systems, that could not be used without
some way of providing this functionality even if it is illegal.

Jack Klein
--
Home: http://jackklein.home.att.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: Sun, 10 Sep 2000 16:10:40 GMT
Raw View
Gil Shafriri wrote:
>=20
> The following code that explicitly convert pointer to function to void*
> compiles OK on vc6.
>=20
> typedef int (*func_ptr_t)();
>=20
> func_ptr_t func_ptr=3D0;
>=20
> void* p =3D reinterpret_cast<void*>(func_ptr);
>=20
> I was thinking that explicit conversion from pointer to function to poi=
nter
> to data is not allowed. Looking at the standard =96 I could not find th=
at it
> is allowed.

Section 5.2.10p1 says "... Conversions that can performed explicitly
using reinterpret_cast are listed below. No other conversion can be
performed explicitly using reinterpret_cast." The conversion you
describe is not on that list.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]