reinterpret_cast between function pointer and void*

163 views
Skip to first unread message

Miro Knejp

unread,
Nov 29, 2016, 7:38:45 AM11/29/16
to ISO C++ Standard - Discussion
Let me start by quoting sections from the current draft N4606

[expr.reinterpret.cast]/1
(...) Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.

[expr.reinterpret.cast]/8
Converting a function pointer to an object pointer 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 a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.

This clearly describes that not all implementations have to support reinterpret_cast between function pointers and object pointers (in my case void*). What I'm uncertain about is how an implementation is supposed to behave if the conversion is not supported. Does the last sentence in p1 mean that a program with such a cast on such a platform has to be ill-formed? It says the conversion itself is implementation-defined, does that also include how to treat it in case the feature is not supported?

Ideally I'd like this to be ill-formed so I can SFINAE/static_assert it out on platforms that don't support this conversion.

Demi Obenour

unread,
Nov 29, 2016, 10:27:32 AM11/29/16
to 'Edward Catmur' via ISO C++ Standard - Discussion

I think that the result of invoking the ensuing function pointer should be implementation defined.  A JIT compiler or dynamic loader will invariably need to perform such a cast in order to jump into the machine code in memory to execute it.  Obviously, this will only succeed if certain machine and OS specific requirements are met.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+unsubscribe@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.

Miro Knejp

unread,
Nov 29, 2016, 11:59:01 AM11/29/16
to std-dis...@isocpp.org

On 29 Nov 2016, at 16:27 , Demi Obenour <demio...@gmail.com> wrote:

I think that the result of invoking the ensuing function pointer should be implementation defined.  A JIT compiler or dynamic loader will invariably need to perform such a cast in order to jump into the machine code in memory to execute it.  Obviously, this will only succeed if certain machine and OS specific requirements are met.

A JIT compiler is still a slave to the hardware and won't be able to do the cast if the hardware cannot do it.

I know that the cast, if supported, is implementation defined and that it has round-trip requirements.

My question is specifically about the case where the platform *does not* support it can *cannot* guarantee the mentioned requirement. On such an implementation is the cast expression required to be ill-formed or is it undefined as per current wording?

David Krauss

unread,
Nov 29, 2016, 12:40:49 PM11/29/16
to std-dis...@isocpp.org

> On 2016–11–29, at 8:38 PM, Miro Knejp <miro....@gmail.com> wrote:
>
> This clearly describes that not all implementations have to support reinterpret_cast between function pointers and object pointers (in my case void*). What I'm uncertain about is how an implementation is supposed to behave if the conversion is not supported. Does the last sentence in p1 mean that a program with such a cast on such a platform has to be ill-formed? It says the conversion itself is implementation-defined, does that also include how to treat it in case the feature is not supported?
>
> Ideally I'd like this to be ill-formed so I can SFINAE/static_assert it out on platforms that don't support this conversion.

It’s not technically ill-formed, but it’s on par with being ill-formed. [intro.compliance]/2.2:

> If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.

However, “on par” may not be enough. [temp.deduct]/8 specifically mentions ill-formedness:

> If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments.


Presuming that SFINAE works, to be sure that the conversion is actually meaningful, it would be best to check the round-trip conversion.

Miro Knejp

unread,
Nov 29, 2016, 1:27:34 PM11/29/16
to std-dis...@isocpp.org
I can only check round-trip property at runtime. I'd prefer code not to compile in the first place if the guarantee isn't given.

So if I understand this correctly a deduction containing an unsupported reinterpret_cast might cause a diagnostic but not make the substitution fail? If so, is there a reason why [intro.compliance]/2.2 does not make using unsupported constructs ill-formed or is that an oversight/defect?

Thiago Macieira

unread,
Nov 29, 2016, 10:40:22 PM11/29/16
to std-dis...@isocpp.org
On terça-feira, 29 de novembro de 2016 04:38:45 PST Miro Knejp wrote:
> Ideally I'd like this to be ill-formed so I can SFINAE/static_assert it out
> on platforms that don't support this conversion.

Reinterpret_cast is not a constant expression, so the point is moot.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Miro Knejp

unread,
Nov 30, 2016, 5:00:31 AM11/30/16
to std-dis...@isocpp.org

> On 30 Nov 2016, at 04:40 , Thiago Macieira <thi...@macieira.org> wrote:
>
> On terça-feira, 29 de novembro de 2016 04:38:45 PST Miro Knejp wrote:
>> Ideally I'd like this to be ill-formed so I can SFINAE/static_assert it out
>> on platforms that don't support this conversion.
>
> Reinterpret_cast is not a constant expression, so the point is moot.

https://godbolt.org/g/jHrLxp

QED

Ville Voutilainen

unread,
Nov 30, 2016, 5:45:29 AM11/30/16
to std-dis...@isocpp.org
And what Q is that D supposed to E? A reinterpret_cast cannot appear
in a constant
expression, and it doesn't appear in such in your example.

Miro Knejp

unread,
Nov 30, 2016, 2:41:47 PM11/30/16
to std-dis...@isocpp.org
He quoted my desire to have it reliably work with SFINAE/static_assert, suggesting in his reply that it's not possible. I clearly showed otherwise.

Regardless my question is still up and I am still not certain whether or not a "conditionally supported" reinterpret_cast, on a platform that doesn't support it, used in a SFINAE context, reliably works or not. If I'm interpreting the sections David quoted right then the tendency is no and I wonder whether that's intended or not, and if not whether it should be changed.

Ville Voutilainen

unread,
Nov 30, 2016, 2:44:45 PM11/30/16
to std-dis...@isocpp.org
On 30 November 2016 at 21:41, Miro Knejp <miro....@gmail.com> wrote:
> Regardless my question is still up and I am still not certain whether or not a "conditionally supported" reinterpret_cast, on a platform that doesn't support it, used in a SFINAE context, reliably works or not. If I'm interpreting the sections David quoted right then the tendency is no and I wonder whether that's intended or not, and if not whether it should be changed.


I interpret those sections so that an implementation that doesn't
support a conditionally supported feature must treat the use of it as
ill-formed,
and since a diagnostic is required, that ill-formedness is also
SFINAEable. So until you find an implementation that does otherwise
and claims
to do so in full conformance, I don't see a need to change anything.

Miro Knejp

unread,
Nov 30, 2016, 3:02:02 PM11/30/16
to std-dis...@isocpp.org
So you're saying that even though [intro.compliance]/2.2 doesn't explicitly mention ill-formedness it still applies to the conditions mentioned in [temp.deduction]/8?

Ville Voutilainen

unread,
Nov 30, 2016, 3:06:31 PM11/30/16
to std-dis...@isocpp.org
On 30 November 2016 at 22:01, Miro Knejp <miro....@gmail.com> wrote:
>> I interpret those sections so that an implementation that doesn't
>> support a conditionally supported feature must treat the use of it as
>> ill-formed,
>> and since a diagnostic is required, that ill-formedness is also
>> SFINAEable. So until you find an implementation that does otherwise
>> and claims
>> to do so in full conformance, I don't see a need to change anything.
>
> So you're saying that even though [intro.compliance]/2.2 doesn't explicitly mention ill-formedness it still applies to the conditions mentioned in [temp.deduction]/8?

Yes.

Richard Smith

unread,
Nov 30, 2016, 4:03:40 PM11/30/16
to std-dis...@isocpp.org
Specifically, [defns.well.formed] defines "well-formed program" as:

  "C++ program constructed according to the syntax rules, diagnosable semantic rules, and the one-definition rule (3.2)."

Attempting to use a conditionally-supported construct that is not supported is a violation of a diagnosable semantic rule (because a diagnostic message is required by [intro.compliance]/2.2), so a program that does so is not a well-formed program. [defns.ill.formed] defines "ill-formed program" as:

  "program that is not well-formed (1.3.29)"

so a program that uses a conditionally-supported construct that is not supported is ill-formed.

[temp.deduction]/8 says that substitution failure occurs if substitution would form a type or expression "that would be ill-formed, with a diagnostic required, if written using the substituted arguments".

Miro Knejp

unread,
Nov 30, 2016, 5:16:21 PM11/30/16
to std-dis...@isocpp.org
Thanks for the explanation.


David Krauss

unread,
Nov 30, 2016, 10:45:02 PM11/30/16
to std-dis...@isocpp.org

> On 2016–11–30, at 2:27 AM, Miro Knejp <miro....@gmail.com> wrote:
>
> I can only check round-trip property at runtime. I'd prefer code not to compile in the first place if the guarantee isn't given.

If both subexpressions are accepted, then the round trip is guaranteed to be an identity mapping.

> So if I understand this correctly a deduction containing an unsupported reinterpret_cast might cause a diagnostic but not make the substitution fail?

Right.

> If so, is there a reason why [intro.compliance]/2.2 does not make using unsupported constructs ill-formed or is that an oversight/defect?

The requirement on use of unsupported constructs is the same as the requirement on ill-formed constructs. Perhaps unsupported could be a subcategory of ill-formed. Alternately, the SFINAE spec could be adjusted to mention conditional support.

David Krauss

unread,
Nov 30, 2016, 10:48:37 PM11/30/16
to std-dis...@isocpp.org
On 2016–12–01, at 3:41 AM, Miro Knejp <miro....@gmail.com> wrote:

He quoted my desire to have it reliably work with SFINAE/static_assert, suggesting in his reply that it's not possible. I clearly showed otherwise.

My intent was only to point out a technicality. It would be fairly surprising if an implementation actually didn’t SFINAE.

If Ville thinks the current spec guarantees it, then perhaps the issue is editorial.

Miro Knejp

unread,
Nov 30, 2016, 10:53:25 PM11/30/16
to std-dis...@isocpp.org
On 01 Dec 2016, at 04:48 , David Krauss <pot...@gmail.com> wrote:


On 2016–12–01, at 3:41 AM, Miro Knejp <miro....@gmail.com> wrote:

He quoted my desire to have it reliably work with SFINAE/static_assert, suggesting in his reply that it's not possible. I clearly showed otherwise.

My intent was only to point out a technicality. It would be fairly surprising if an implementation actually didn’t SFINAE.
I was referring to Thiago's comment.

Thiago Macieira

unread,
Dec 1, 2016, 11:14:54 AM12/1/16
to std-dis...@isocpp.org
Interesting, I hadn't thought of that. Thanks for the example!
Reply all
Reply to author
Forward
0 new messages