@@ -151,6 +151,13 @@ <h3><a href="#definitions"> 1.1 Definitions </a></h3>
151
151
A function that runs the destructors for non-static data members of T and
152
152
non-virtual direct base classes of T.
153
153
154
+ < p >
155
+ < dt > < i > basic ABI properties</ i > of a type T</ dt >
156
+ < dd >
157
+ The basic representational properties of a type decided by the base C ABI,
158
+ including its size, its alignment, its treatment by calling conventions,
159
+ and the representation of pointers to it.
160
+
154
161
< p >
155
162
< dt > < i > complete object destructor</ i > of a class T</ dt >
156
163
< dd >
@@ -686,40 +693,110 @@ <h3><a href="#pod"> 2.2 POD Data Types </a></h3>
686
693
< a name ="member-pointers "> </ a >
687
694
< h3 > < a href ="#member-pointers "> 2.3 Member Pointers </ a > </ h3 >
688
695
696
+ < a name ="data-member-pointers "> </ a >
697
+ < h4 > < a href ="#data-member-pointers "> 2.3.1 Data Member Pointers </ a > </ h4 >
698
+
689
699
< p >
690
- A pointer to data member is an offset from the base
691
- address of the class object containing it,
692
- represented as a < code > ptrdiff_t</ code > .
693
- It has the size and alignment attributes of a < code > ptrdiff_t</ code > .
694
- A NULL pointer is represented as -1.
700
+ The basic ABI properties of data member pointer types are those
701
+ of < code > ptrdiff_t</ code > .
695
702
696
703
< p >
697
- A pointer to member function is a pair < ptr , adj > as follows:
704
+ A data member pointer is represented as the data member's offset in bytes
705
+ from the address point of an object of the base type, as a
706
+ < code > ptrdiff_t</ code > .
698
707
699
- < dl >
700
708
< p >
701
- < dt > < code > ptr</ code > :
702
- < dd > For a non-virtual function, this field is a simple function pointer.
703
- (Under current base Itanium psABI conventions,
704
- that is a pointer to a GP/function address pair.)
705
- For a virtual function,
706
- it is 1 plus the virtual table offset (in bytes) of the function,
707
- represented as a < code > ptrdiff_t</ code > .
708
- The value zero represents a NULL pointer,
709
- independent of the adjustment field value below.
709
+ A null data member pointer is represented as an offset of < code > -1</ code > .
710
+ Unfortunately, it is possible to generate an data member pointer with an
711
+ offset of < code > -1</ code > using explicit derived-to-base conversions.
712
+ If this is done, implementations following this ABI may misbehave.
713
+ < span class ="future-abi "> Recommendation for new platforms: consider using
714
+ < code > PTRDIFF_MIN</ code > as the null data member pointer instead.</ span >
710
715
711
716
< p >
712
- < dt > < code > adj</ code > :
713
- < dd > The required adjustment to < i > this</ i > ,
714
- represented as a < code > ptrdiff_t</ code > .
715
- </ dl >
717
+ Note that by < code > [dcl.init]</ code > , "zero initialization" of a data
718
+ member pointer object stores a null pointer value into it. Under this
719
+ representation, that value has a non-zero bit representation. On most
720
+ modern platforms, data member pointers are the only type with this
721
+ property.
716
722
717
723
< p >
718
- It has the size, data size, and alignment
719
- of a class containing those two members, in that order.
720
- (For 64-bit Itanium, that will be 16, 16, and 8 bytes respectively.)
724
+ Base-to-derived and derived-to-base conversions of a non-null data member
725
+ pointer can be performed by adding or subtracting (respectively) the static
726
+ offset of the base within the derived class. The C++ standard does not
727
+ permit base-to-derived and derived-to-base conversions of member pointers
728
+ to cross a < code > virtual</ code > base relationship, and so a static offset
729
+ is always known.
721
730
731
+ < a name ="member-function-pointers "> </ a >
732
+ < h4 > < a href ="#member-function-pointers "> 2.3.2 Member Function Pointers </ a > </ h4 >
733
+
734
+ < p >
735
+ The basic ABI properties of member function pointer types are those of
736
+ the following class:
737
+
738
+ < pre >
739
+ struct {
740
+ fnptr_t ptr;
741
+ ptrdiff_t adj;
742
+ };
743
+ </ pre >
722
744
745
+ where < code > fnptr_t</ code > is the appropriate function-pointer type
746
+ for the member type.
747
+
748
+ < p >
749
+ A member function pointer for a non-virtual function is represented
750
+ with < code > ptr</ code > set to a function pointer to the function,
751
+ using the base ABI's representation of function pointers.
752
+
753
+ < p >
754
+ A member function pointer for a virtual function is represented
755
+ with < code > ptr</ code > set to 1 plus the virtual table offset of
756
+ the function (in bytes), converted to a function pointer as if by < code > reinterpret_cast<fnptr_t>(uintfnptr_t(1 + offset))</ code > ,
757
+ where < code > uintfnptr_t</ code > is an unsigned integer of the same
758
+ size as < code > fnptr_t</ code > .
759
+
760
+ < p >
761
+ In both cases, < code > adj</ code > stores the offset (in bytes) which
762
+ must be added to a pointer to the base type before the call can be
763
+ made. For a virtual member function pointer, the v-table is loaded
764
+ from the adjusted address.
765
+
766
+ < p >
767
+ The representation of virtual member function pointers requires the
768
+ representation of a function pointer to a non-static member function
769
+ to never have its lowest bit set. On most platforms, this is either
770
+ always true, or it can be made true at little cost. (For example,
771
+ on most platforms a function pointer is just the address of the
772
+ first instruction in the function. Many architectures align all
773
+ instructions to at least 2 bytes; even on architectures where that's
774
+ not true, or where functions aren't byte-addressed, the compiler can
775
+ just increase the alignment of non-static member functions until the
776
+ low bit of the address is always reliably zero.) However, some platforms
777
+ use the low bit of a function pointer for special purposes, such as to
778
+ distinguish THUMB functions on ARM. Such platforms must use a slightly
779
+ different representation: the virtual/non-virtual bit is instead stored
780
+ as the lowest bit of < code > adj</ code > , and the adjustment value is
781
+ stored left-shifted by 1.
782
+
783
+ < p >
784
+ A null member function pointer is represented by a null value for
785
+ < code > ptr</ code > . (This assumes that the low bit of a null pointer
786
+ is not 1; platforms with non-zero bit representations for null function
787
+ pointers may need an adjusted rule.) The value of < code > adj</ code >
788
+ is not specified unless the alternative virtual-bit representation
789
+ is being used, in which case the lowest bit of < code > adj</ code > must
790
+ also be zero but the remaining bits are still unspecified.
791
+
792
+ < p >
793
+ Base-to-derived and derived-to-base conversions of a member function
794
+ pointer can be performed by adding or subtracting (respectively) the
795
+ static offset of the base within the derived class to the value of
796
+ < code > adj</ code > . In the alternative virtual-bit representation,
797
+ the addend must be shifted by one. Because the adjustment does not
798
+ factor into whether a member function pointer is null, this can be
799
+ done unconditionally when performing a conversion.
723
800
724
801
< p > < hr > < p >
725
802
< a name ="class-types ">
0 commit comments