Movatterモバイル変換


[0]ホーム

URL:


This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-12-20


195. Converting between function and object pointers

Section:7.6.1.10  [expr.reinterpret.cast]    Status:CD1    Submitter:Steve Clamage    Date:12 Jan 2000

[Voted into WP at April 2005 meeting.]

It is currently not permitted to cast directly between a pointer tofunction type and a pointer to object type. This conversion is notlisted in 7.6.1.9 [expr.static.cast] and7.6.1.10 [expr.reinterpret.cast] and thusrequires a diagnostic to be issued. However, if a sufficiently longintegral type exists (as is the case in many implementations), it ispermitted to cast between pointer to function types and pointer toobject types using that integral type as an intermediary.

In C the cast results in undefined behavior and thus does notrequire a diagnostic, and Unix C compilers generally do not issueone. This fact is used in the definition of the standard Unixfunctiondlsym, which is declared to returnvoid*but in fact may return either a pointer to a function or a pointer toan object. The fact that C++ compilers are required to issue adiagnostic is viewed as a "competitive disadvantage" for the language.

Suggested resolution: Add wording to7.6.1.10 [expr.reinterpret.cast] allowingconversions between pointer to function and pointer to object types,if the implementation has an integral data type that can be used as anintermediary.

Several points were raised in opposition to this suggestion:


  1. Early C++ supported this conversion and it was deliberatelyremoved during the standardization process.
  2. The existence of an appropriate integral type is irrelevant towhether the conversion is "safe." The condition should be on whetherinformation is lost in the conversion or not.
  3. There are numerous ways to address the problem at animplementation level rather than changing the language. For example,the compiler could recognize the specific case ofdlsym andomit the diagnostic, or the C++ binding todlsym could bechanged (using templates, for instance) to circumvent the violation.
  4. The conversion is, in fact, not supported by C; thedlsymfunction is simply relying on non-mandated characteristics of Cimplementations, and we would be going beyond the requirements of Ccompatibility in requiring (some) implementations to support theconversion.
  5. This issue is in fact not a defect (omitted or self-contradictoryrequirements) in the current Standard; the proposed change wouldactually be an extension and should not be considered until the fullreview of the IS.
  6. dlsym appears not to be used very widely, and thedeclaration in the header file is not problematic, only calls to it.Since C code generally requires some porting to be valid C++ anyway,this should be considered one of those items that requires porting.

Martin O'Riordan suggested an alternative approach:


The advantage of this approach is that it would permit writingportable, well-defined programs involving such conversions. However,it breaks the current degree of compatibility between old and newcasts, and it adds functionality todynamic_cast which is notobviously related to its current meaning.

Notes from 04/00 meeting:

Andrew Koenig suggested yet another approach: specify that "nodiagnostic is required" if the implementation supports the conversion.

Later note:

It was observed that conversion between function and data pointersis listed as a "common extension" in C99.

Notes on the 10/01 meeting:

It was decided that we want the conversion defined in such a way thatit always exists but is always undefined (as opposed to existing onlywhen the size relationship is appropriate, and being implementation-definedin that case). This would allow an implementation to issue an errorat compile time if the conversion does not make sense.

Bill Gibbons notes that the definitions of the other similar casts areinconsistent in this regard. Perhaps they should be updated as well.

Proposed resolution (April 2003):

After 7.6.1.10 [expr.reinterpret.cast] paragraph 6, insert:

A pointer to afunction can be explicitly converted to a pointer to a function of a differenttype. The effect of calling a function through a pointer to a functiontype (9.3.4.6 [dcl.fct])that is not the same as the type used in the definition of the function isundefined. Except that converting an rvalue of type ``pointer toT1''to the type ``pointer toT2'' (whereT1 andT2 arefunction types) and back to its original type yields the original pointervalue, the result of such a pointer conversion is unspecified. [Note: seealso 7.3.12 [conv.ptr] for more details of pointer conversions. ]It is implementation defined whether a conversion from pointer to object topointer to function and/or a conversion from pointer to function to pointer toobject exist.
and in paragraph 10:
An lvalue expression of typeT1 can be cast to the type``reference toT2''ifT1 andT2 are object types and an expression oftype ``pointer toT1'' can be explicitly converted to the type``pointer toT2'' using a reinterpret_cast. That is, a referencecastreinterpret_cast< T& >(x) has the same effectas the conversion*reinterpret_cast< T* >(&x) withthe built-in& and* operators.The result is an lvalue that refers to the same object as the source lvalue,but with a different type. No temporary is created, no copy is made, andconstructors (11.4.5 [class.ctor]) or conversion functions(11.4.8 [class.conv]) are not called.

Drafting Note:

If either conversion exists, the implementation already has to define thebehavior (paragraph 3).

Notes from April 2003 meeting:

The new consensus is that if the implementation allowsthis cast, pointer-to-function converted to pointer-to-object convertedback to the original pointer-to-function should work; anything elseis undefined behavior. If the implementation does not allow the cast,it should be ill-formed.

Tom Plum is investigating a new concept, that of a"conditionally-defined" feature, which may be applicable here.

Proposed Resolution (October, 2004):

(See paper J16/04-0067 = WG21 N1627 for background material andrationale for this resolution. The resolution proposed here differsonly editorially from the one in the paper.)

  1. Insert the following into Clause 3 [intro.defs] and renumberall following definitions accordingly:

    1.3.2  conditionally-supported behavior

    behavior evoked by a program construct that is not a mandatoryrequirement of this International Standard. If a given implementationsupports the construct, the behavior shall be as described herein;otherwise, the implementation shall document that the construct is notsupported and shall treat a program containing an occurrence of theconstruct as ill-formed (Clause 3 [intro.defs]).

  2. Add the indicated words to 4.1 [intro.compliance] paragraph 2,bullet 2:

  3. Insert the following as a new paragraph following 7.6.1.10 [expr.reinterpret.cast] paragraph 7:

    Converting a pointer to a function to a pointer to an object type orvice versa evokes conditionally-supported behavior. In any suchconversion supported by an implementation, converting from an rvalueof one type to the other and back (possibly with differentcv-qualification) shall yield the original pointer value; mappingsbetween pointers to functions and pointers to objects are otherwiseimplementation-defined.
  4. Change 9.11 [dcl.asm] paragraph 1 as indicated:

    The meaning of anAnasm declarationevokesconditionally-supported behavior. If supported, its meaning isimplementation-defined.
  5. Change 9.12 [dcl.link] paragraph 2 as indicated:

    Thestring-literal indicates the required language linkage.The meaning of thestring-literal is implementation-defined. A linkage-specification with a string thatis unknown to the implementation is ill-formed.This International Standardspecifies the semantics of C and C++ language linkage. Other values of thestring-literal evoke conditionally-supported behavior, withimplementation-defined semantics. [Note: Therefore, alinkage-specification with astring-literal that isunknown to the implementation requires a diagnostic.When thestring-literal in a linkage-specification names a programminglanguage, the spelling of the programming language's name isimplementation-defined. [Note:It is recommended that thespelling be taken from the document defining that language, forexampleAda (notADA) andFortran orFORTRAN (depending on the vintage).The semantics of alanguage linkage other than C++ or C are implementation-defined. ]
  6. Change Clause 13 [temp] paragraph 4 as indicated:

    A template, a template explicit specialization (13.9.4 [temp.expl.spec]), or a class template partial specialization shallnot have C linkage. If the linkage of one of these is something otherthan C or C++, thebehavior is implementation-definedresultis conditionally-supported behavior, with implementation-definedsemantics.



[8]ページ先頭

©2009-2026 Movatter.jp