@@ -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,167 @@ <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 a 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
+ a different representation for data member pointers, such as left-shifting
715
+ the offset by one and using a non-zero low bit to indicate a non-null
716
+ value.</ span >
710
717
711
718
< 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 >
719
+ Note that by < code > [dcl.init]</ code > , "zero initialization" of a data
720
+ member pointer object stores a null pointer value into it. Under this
721
+ representation, that value has a non-zero bit representation. On most
722
+ modern platforms, data member pointers are the only type with this
723
+ property.
724
+
725
+ < p >
726
+ Base-to-derived and derived-to-base conversions of a non-null data member
727
+ pointer can be performed by adding or subtracting (respectively) the static
728
+ offset of the base within the derived class. The C++ standard does not
729
+ permit base-to-derived and derived-to-base conversions of member pointers
730
+ to cross a < code > virtual</ code > base relationship, and so a static offset
731
+ is always known.
732
+
733
+ < a name ="member-function-pointers "> </ a >
734
+ < h4 > < a href ="#member-function-pointers "> 2.3.2 Member Function Pointers </ a > </ h4 >
735
+
736
+ < p >
737
+ Several different representions of member function pointers are in use.
738
+ The standard representation relies on several assumptions about the
739
+ platform, such as that the low bit of a function pointer to a non-virtual
740
+ member function is always zero. For platforms where this is not reasonable
741
+ to guarantee, an alternate representation must be used. One such
742
+ representation, used on the 32-bit ARM architecture, is also described here.
743
+
744
+ < p >
745
+ In all representations, the basic ABI properties of member function
746
+ pointer types are those of the following class, where < code > fnptr_t</ code >
747
+ is the appropriate function-pointer type for a member function of this type:
748
+
749
+ < pre >
750
+ struct {
751
+ fnptr_t ptr;
752
+ ptrdiff_t adj;
753
+ };
754
+ </ pre >
716
755
717
756
< 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.)
757
+ A member function pointer for a non-virtual member function is represented
758
+ with < code > ptr </ code > set to a pointer to the function, using the base
759
+ ABI's representation of function pointers.
721
760
761
+ < p >
762
+ In the standard representation, a member function pointer for a virtual
763
+ function is represented with < code > ptr</ code > set to 1 plus the function's
764
+ v-table entry offset (in bytes), converted to a function pointer as if by
765
+ < code > reinterpret_cast<fnptr_t>(uintfnptr_t(1 + offset))</ code > ,
766
+ where < code > uintfnptr_t</ code > is an unsigned integer of the same
767
+ size as < code > fnptr_t</ code > .
768
+
769
+ < p >
770
+ In both of these cases, < code > adj</ code > stores the offset (in bytes)
771
+ which must be added to the < code > this</ code > pointer before the call.
722
772
773
+ < p >
774
+ In the standard representation, a null member function pointer is
775
+ represented with < code > ptr</ code > set to a null pointer. The value
776
+ of < code > adj</ code > is unspecified for null member function pointers.
777
+
778
+ < p >
779
+ The standard representation relies on some assumptions which are
780
+ true for most platforms:
781
+
782
+ < ul compact >
783
+ < li > The low bit of a function pointer to a non-static member function
784
+ is never set. On most platforms, this is either always true or
785
+ can be made true at little cost. For example, on platforms where
786
+ a function pointer is just the address of the first instruction in the
787
+ function, the implementation can ensure that this addresss is always
788
+ sufficiently aligned to make the low bit zero for non-static member
789
+ functions; often this is required by the underlying architecture.</ li >
790
+
791
+ < li > A null function pointer can be distinguished from a virtual
792
+ offset value. On most platforms, this is always true because the
793
+ null function pointer is the zero value.</ li >
794
+
795
+ < li > The offset to a v-table entry is never odd. On most platforms,
796
+ the size of a v-table entry is even because the architecture is
797
+ byte-addressed and pointers are even-sized.</ li >
798
+
799
+ < li > A virtual call can be performed knowing only the addresss of a
800
+ v-table entry and the type of the virtual function. On most
801
+ platforms, a v-table entry is equivalent to a function pointer,
802
+ and the type of that function pointer can be determined from the
803
+ member pointer type.</ li >
804
+ </ ul >
805
+
806
+ < p >
807
+ However, there are exceptions. For example, on the 32-bit ARM
808
+ architecture, the low bit of a function pointer determines whether
809
+ the function begins in THUMB mode. Such platforms must use an
810
+ alternate representation.
811
+
812
+ < p >
813
+ In the 32-bit ARM representation, the < code > this</ code > -adjustment
814
+ stored in < code > adj</ code > is left-shifted by one, and the low bit
815
+ of < code > adj</ code > indicates whether < code > ptr</ code > is a function
816
+ pointer (including null) or the offset of a v-table entry. A virtual
817
+ member function pointer sets < code > ptr</ code > to the v-table entry
818
+ offset as if by
819
+ < code > reinterpret_cast<fnptr_t>(uintfnptr_t(offset))</ code > .
820
+ A null member function pointer sets < code > ptr</ code > to a null
821
+ function pointer and must ensure that the low bit of < code > adj</ code >
822
+ is clear; the upper bits of < code > adj</ code > remain unspecified.
823
+
824
+ < p > A member function pointer is null if < code > ptr</ code > is equal
825
+ to a null function pointer and (only when using the 32-bit ARM
826
+ representation) the low bit of < code > adj</ code > is clear.
827
+
828
+ < p > Two member function pointers are equal if they are both null or
829
+ if their corresponding values of < code > ptr</ code > and < code > adj</ code >
830
+ are equal. Note that the C++ standard does not require member pointers
831
+ to the same virtual member function to compare equal; implementations
832
+ using this ABI will do so, but only if the member pointers are built
833
+ using the same v-table offset, which they may not be in the presence
834
+ of multiple inheritance or overrides with covariant return types.
835
+
836
+ < p >
837
+ Base-to-derived and derived-to-base conversions of a member function
838
+ pointer can be performed by adding or subtracting (respectively) the
839
+ static offset of the base within the derived class to the stored
840
+ < code > this</ code > -adjustment value. In the standard representation,
841
+ this simply means adding it to < code > adj</ code > ; in the 32-bit ARM
842
+ representation, the addend must be left-shifted by one. Because the
843
+ adjustment does not factor into whether a member function pointer is
844
+ null, this addition can be done unconditionally when performing a
845
+ conversion.
846
+
847
+ < p >
848
+ A call is performed as follows:
849
+
850
+ < ol >
851
+ < li > Add the stored adjustment to the < code > this</ code > address.</ li >
852
+ < li > If the member pointer stores a v-table entry offset, load the
853
+ v-table from the adjusted < code > this</ code > address and call
854
+ the v-table entry at the stored offset.</ li >
855
+ < li > Otherwise, call the stored function pointer.</ li >
856
+ </ ol >
723
857
724
858
< p > < hr > < p >
725
859
< a name ="class-types ">
0 commit comments