Casting function pointers to and from void*

?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Julián Albo said:
Did you have? Looks like you are asking for advice because you haven't.

Sorry, I make a mistake between your name and the OP.
 
G

Gavin Deane

Pete said:
You're welcome to spend as much time as you like seeking purity. I'll
trust Unix compilers to continue support standard idioms such as storing
function addresses in void*'s, and I'll have robust, working code long
before you do.

Something must be giving you the confidence to regard that as a
standard idiom that will benefit from continuing support. It's not the
language standard. Is it the compiler documentation? I hope I was clear
in my point that I regard compiler documentation of non-standard
behaviour an equally valid source of such confidence as the standard
itself.

If it's not the compiler documentation, it must be something else.
Perhaps simply an unwritten understanding amongst Unix compiler writers
that their customers expect and rely on this behaviour. If so, would it
not be better for the compiler to document the behaviour, so that the
unwritten becomes written and those new to Unix programming don't have
to learn the folklore by word of mouth?

Gavin Deane
 
A

Alf P. Steinbach

* Gavin Deane:
Something must be giving you the confidence to regard that as a
standard idiom that will benefit from continuing support. It's not the
language standard. Is it the compiler documentation? I hope I was clear
in my point that I regard compiler documentation of non-standard
behaviour an equally valid source of such confidence as the standard
itself.

Presumably Pete is referring to any reliable system documentation
whatsoever, such as (1) compiler documentation, and/or (2) the Posix
standard.

There is a difference between 100% portable standard C++ code and
in-practice C++ code.

One difference is, of course <g>, that in 100% portable C++ code you
can't do any i/o, since some systems have no i/o devices compatible with
the forms of i/o supported by the standard library... So there's really
not very much that can be done in 100% portable C++. Even "Hello,
world!" is not 100% portable: it requires a system with text display.
So the question is always (although unfortunately most often left
unstated): what is the range of systems that this code is meant to be
portable to? When that range is "Posix-compliant systems", storing
function pointers in void* is perfectly OK, as far as I know.
 
G

Gavin Deane

Alf said:
* Gavin Deane:

Presumably Pete is referring to any reliable system documentation
whatsoever, such as (1) compiler documentation, and/or (2) the Posix
standard.

I'm not very familiar with the Posix standard, but if it requires
certain behaviour of C++ programs (e.g. function pointers to be
storable in void*), and the compiler documentation states something to
the effect that "this compiler implements all behaviour required by the
Posix standard" then clearly that is just as good. You know the
compiler author intends for function pointers to be storable in void*
and you know that if you write such code only a compiler bug can cause
it not to work.
There is a difference between 100% portable standard C++ code and
in-practice C++ code.

While I recognise that portability is often the reason for the kind of
argument I'm making, note that I haven't mentioned portability at all
in this thread.
One difference is, of course <g>, that in 100% portable C++ code you
can't do any i/o, since some systems have no i/o devices compatible with
the forms of i/o supported by the standard library... So there's really
not very much that can be done in 100% portable C++. Even "Hello,
world!" is not 100% portable: it requires a system with text display.
So the question is always (although unfortunately most often left
unstated): what is the range of systems that this code is meant to be
portable to? When that range is "Posix-compliant systems", storing
function pointers in void* is perfectly OK, as far as I know.

I agree with all that, however I'm not actually coming from the point
of view of portability at all. If the question is "what is the range of
systems that this code is meant to be portable to?", even if the answer
is "none at all, the code will only ever run on the current system", I
still believe is simply good engineering practice that all the code you
write relies only on behaviour documented (either directly or by
reference to another source) by the compiler author.

Gavin Deane
 
A

Andre Kostur

* Gavin Deane:

Presumably Pete is referring to any reliable system documentation
whatsoever, such as (1) compiler documentation, and/or (2) the Posix
standard.

There is a difference between 100% portable standard C++ code and
in-practice C++ code.

One difference is, of course <g>, that in 100% portable C++ code you
can't do any i/o, since some systems have no i/o devices compatible
with the forms of i/o supported by the standard library... So there's
really not very much that can be done in 100% portable C++. Even
"Hello, world!" is not 100% portable: it requires a system with text
display. So the question is always (although unfortunately most often
left unstated): what is the range of systems that this code is meant
to be portable to? When that range is "Posix-compliant systems",
storing function pointers in void* is perfectly OK, as far as I know.

Well... arguably it (Hello World) is 100% portable C++ (for a hosted
environment). It is only using facilities provided by the Standard
Library. It puts "Hello, world!" into some sort of output sink. Wherever
the host decides to put that output is up to the OS & platform (Output to a
serial line, output to a screen, output to a printer, or perhaps output to
the proverbial bit bucket. In any case, it goes _somewhere_.).
 
P

Pete Becker

Alf said:
There is a difference between 100% portable standard C++ code and
in-practice C++ code.

And note that 100% standard C++ code is not ipso facto portable.
Compilers aren't perfect. Portability is a real-world concept, not a
theoretical one.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
G

Greg

Marcus said:
Greg said:
Function-to-object pointer conversions have been added to standard C++
as a "conditionally supported" conversion using reinterpret_cast<>:

"Converting a pointer to a function into a pointer to an object type or
vice versa is conditionally-supported. The meaning of such a conversion
is implementation defined, except that if an implementation supports
conversions in both directions, converting an rvalue of one type to the
other type and back, possibly with different cv-qualification, shall
yield the original pointer value." [expr.reinterpret.cast/8]

Interesting, thanks.
Conditionally-supported behavior is one that an implementation is not
required to support. But an implementation does support the feature
must then implement the feature as specified.

Is there a consolidated list of other "conditionally-supported"
features?

Not that I know of, so I tried putting together a list myself. Aside
from the pointer-to-object opointer-to-function conversion, the other
conditionally-supported behaviors that I found, are:

A character escaped with a backslash:
"Escape sequences in which the character following the backslash is not
listed in Table 6 are conditionally-supported, with
implementation-defined semantics"


A non-POD type parameter in variable argument list:
"Passing an argument of non-POD class type (clause 9) with no
corresponding parameter is conditionally-supported, with
implementation-defined semantics."


The "asm" directive:
"The asm declaration is conditionally-supported; its meaning is
implementation-defined."


Templates with non-C, non-C++ language linkage
"A template, a template explicit specialization (14.7.3), and a class
template partial specialization shall not have C linkage. Use of a
linkage specification other than C or C++ with any of these constructs
is conditionally-supported, with implementation-defined semantics"

Not the most exciting list of features, I would admit. Perhaps
"conditionally-supported" should mean that an implementation has to
support the feature only if someone notices that the feature is
missing.

Greg
 
M

Marcus Kwok

Greg said:
Not that I know of, so I tried putting together a list myself. Aside
from the pointer-to-object opointer-to-function conversion, the other
conditionally-supported behaviors that I found, are:

A character escaped with a backslash:

A non-POD type parameter in variable argument list:

The "asm" directive:

Templates with non-C, non-C++ language linkage

Not the most exciting list of features, I would admit.

I agree, but thanks anyway :)
 

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,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top