Topic: Member-pointers to a unknown class


Author: stackmachine@hotmail.com
Date: Thu, 22 Nov 2012 21:46:16 -0800 (PST)
Raw View
------=_Part_5_26713160.1353649576145
Content-Type: text/plain; charset=ISO-8859-1

Hi there,

I recently implemented my own std::function to compare them
performance-wise. What I'd have really liked to have is a memberfunction
pointer to a unknown class for the purpose of type erasure. This would
relate to a 'normal' memberfunction pointer like a void* to a T*. In
particular, you can't really do anything with it, other than
static_cast-ing it back to the original type. A cast from a memberfunction
pointer of known type to this new pointer should be implicit.

Example:
struct foo
{
        void bar();
};

// ...

void (foo::* kpf) () = &foo::bar; // as usual
void (void::* upf) () = kpf; // implicit conversion
auto kpf2 = static_cast<void (foo::*) ()>(upf); // static_cast required
For member pointers this would work the exact same way.

What I did instead was to cast the pointer to a memberfunction pointer to a
dummy-class. This however does not work with MSVC, because different
'kinds' of memberfunction pointers have different sizes. Such a new kind of
pointer would solve this problem.

--




------=_Part_5_26713160.1353649576145
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi there,<div><br></div><div>I recently implemented my own std::function to=
 compare them performance-wise. What I'd have really liked to have is a mem=
berfunction pointer to a unknown class for the purpose of type erasure. Thi=
s would relate to a 'normal' memberfunction pointer like a void* to a T*. I=
n particular, you can't really do anything with it, other than static_cast-=
ing it back to the original type. A cast from a memberfunction pointer of k=
nown type to this new pointer should be implicit.</div><div><br></div><div>=
Example:</div><div><div style=3D"background-color: rgb(250, 250, 250); bord=
er: 1px solid rgb(187, 187, 187); word-wrap: break-word;" class=3D"prettypr=
int"><code class=3D"prettyprint"><div class=3D"subprettyprint"><div style=
=3D"font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 2=
55, 255);"><span style=3D"color: #008;" class=3D"styled-by-prettify">struct=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo<br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nb=
sp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> bar<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// ...</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> kp=
f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">bar</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// as usual</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">void</span><font color=3D"#666600=
"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::*</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> upf</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> kpf</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// implicit conversion</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font><span styl=
e=3D"color: rgb(136, 0, 0);"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> kpf2 </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">static_cast</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::*)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">()&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">upf</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// static_cast re=
quired</span></span></div></div></code></div>For member pointers this would=
 work the exact same way.</div><div><br></div><div>What I did instead was t=
o cast the pointer to a memberfunction pointer to a dummy-class. This howev=
er does not work with MSVC, because different 'kinds' of memberfunction poi=
nters have different sizes. Such a new kind of pointer would solve this pro=
blem.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_5_26713160.1353649576145--

.


Author: stackmachine@hotmail.com
Date: Thu, 22 Nov 2012 23:13:36 -0800 (PST)
Raw View
------=_Part_27_13639198.1353654816227
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Actually, let me take this a step further. C++ violatates its own principle=
=20
(don't pay for what you don't use) by implicitly requiring pointers to=20
members to be of the same size. (5.2.10.10)

> =20
>    -=20
>   =20
>    =97  converting a prvalue of type =93pointer to member function=94 to =
a=20
>    different pointer to member function type and back to its original typ=
e=20
>    yields the original pointer to member value.=20
>     -=20
>   =20
>    =97  converting a prvalue of type =93pointer to data member of X of ty=
pe T1=94=20
>    to the type =93pointer to data member of Y of type T2=94 (where the=20
>    alignment requirements of T2 are no stricter than those of T1) and=20
>    back to its original type yields the original pointer to member value.=
=20
>   =20
> I'd like to remove these requirements and instead let T void::* be a=20
pointer large enough to hold any kind of member-pointer to T. Unfortunately=
=20
this would cause code to silently break, therefore it might be feasible to=
=20
disallow such casts entirely, or define categories (incomplete class type,=
=20
class type with virtual inheritance, ...) of such casts that should succeed=
..

--=20




------=_Part_27_13639198.1353654816227
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Actually, let me take this a step further. C++ violatates its own principle=
 (don't pay for what you don't use) by implicitly requiring pointers to mem=
bers to be of the same size. (5.2.10.10)<div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left=
-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">
 =09
=09
=09
  <div class=3D"column">
   <ul style=3D"list-style-type: none">
    <li>
     <p><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'">=
=97 &nbsp;converting a prvalue of type =93pointer to member function=94 to =
a different pointer to member function
type and back to its original type yields the original pointer to member va=
lue.
</span></p>
    </li>
    <li>
     <p><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'">=
=97 &nbsp;converting a prvalue of type =93pointer to data member of </span>=
<span style=3D"font-size: 10.000000pt; font-family: 'LMMono10'">X </span><s=
pan style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'">of type </sp=
an><span style=3D"font-size: 10.000000pt; font-family: 'LMMono10'">T1=94 </=
span><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'">to th=
e type =93pointer to data
member of </span><span style=3D"font-size: 10.000000pt; font-family: 'LMMon=
o10'">Y </span><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman=
10'">of type </span><span style=3D"font-size: 10.000000pt; font-family: 'LM=
Mono10'">T2=94 </span><span style=3D"font-size: 10.000000pt; font-family: '=
LMRoman10'">(where the alignment requirements of </span><span style=3D"font=
-size: 10.000000pt; font-family: 'LMMono10'">T2 </span><span style=3D"font-=
size: 10.000000pt; font-family: 'LMRoman10'">are no stricter than those of =
</span><span style=3D"font-size: 10.000000pt; font-family: 'LMMono10'">T1)
</span><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'">and=
 back to its original type yields the original pointer to member value.&nbs=
p;</span></p></li></ul></div></blockquote><div>I'd like to remove these req=
uirements and instead let T void::* be a pointer large enough to hold any k=
ind of member-pointer to T. Unfortunately this would cause code to silently=
 break, therefore it might be feasible to disallow such casts entirely, or =
define categories (incomplete class type, class type with virtual inheritan=
ce, ...) of such casts that should succeed.</div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_27_13639198.1353654816227--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 23 Nov 2012 00:35:48 -0800 (PST)
Raw View
------=_Part_2002_26611665.1353659748300
Content-Type: text/plain; charset=ISO-8859-1

Except that's impossible to implement, because depending on TUs and what's
declared, the size required changes.

--




------=_Part_2002_26611665.1353659748300
Content-Type: text/html; charset=ISO-8859-1

Except that's impossible to implement, because depending on TUs and what's declared, the size required changes.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_2002_26611665.1353659748300--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 00:41:29 -0800 (PST)
Raw View
------=_Part_285_21386377.1353660089894
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Thursday, November 22, 2012 11:13:36 PM UTC-8, stackm...@hotmail.com=20
wrote:
>
> Actually, let me take this a step further. C++ violatates its own=20
> principle (don't pay for what you don't use) by implicitly requiring=20
> pointers to members to be of the same size. (5.2.10.10)
>
>> =20
>>    -=20
>>   =20
>>    =97  converting a prvalue of type =93pointer to member function=94 to=
 a=20
>>    different pointer to member function type and back to its original ty=
pe=20
>>    yields the original pointer to member value.=20
>>     -=20
>>   =20
>>    =97  converting a prvalue of type =93pointer to data member of X of t=
ype T1=94=20
>>    to the type =93pointer to data member of Y of type T2=94 (where the=
=20
>>    alignment requirements of T2 are no stricter than those of T1) and=20
>>    back to its original type yields the original pointer to member value=
..=20
>>   =20
>> I'm not sure I see how that's paying for something you don't use any mor=
e=20
than having structs that have alignment padding.


--=20




------=_Part_285_21386377.1353660089894
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<br><br>On Thursday, November 22, 2012 11:13:36 PM UTC-8, stackm...@hotmail=
..com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Actually, let me ta=
ke this a step further. C++ violatates its own principle (don't pay for wha=
t you don't use) by implicitly requiring pointers to members to be of the s=
ame size. (5.2.10.10)<div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex">
 =09
=09
=09
  <div>
   <ul style=3D"list-style-type:none">
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to member function=94 to a dif=
ferent pointer to member function
type and back to its original type yields the original pointer to member va=
lue.
</span></p>
    </li>
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to data member of </span><span=
 style=3D"font-size:10.000000pt;font-family:'LMMono10'">X </span><span styl=
e=3D"font-size:10.000000pt;font-family:'LMRoman10'">of type </span><span st=
yle=3D"font-size:10.000000pt;font-family:'LMMono10'">T1=94 </span><span sty=
le=3D"font-size:10.000000pt;font-family:'LMRoman10'">to the type =93pointer=
 to data
member of </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10=
'">Y </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">o=
f type </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10'">=
T2=94 </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=
(where the alignment requirements of </span><span style=3D"font-size:10.000=
000pt;font-family:'LMMono10'">T2 </span><span style=3D"font-size:10.000000p=
t;font-family:'LMRoman10'">are no stricter than those of </span><span style=
=3D"font-size:10.000000pt;font-family:'LMMono10'">T1)
</span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">and ba=
ck to its original type yields the original pointer to member value.&nbsp;<=
/span></p></li></ul></div></blockquote><div></div></div></blockquote><div>I=
'm not sure I see how that's paying for something you don't use any more th=
an having structs that have alignment padding.</div><br><br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_285_21386377.1353660089894--

.


Author: stackmachine@hotmail.com
Date: Fri, 23 Nov 2012 00:43:43 -0800 (PST)
Raw View
------=_Part_167_172249.1353660223686
Content-Type: text/plain; charset=ISO-8859-1

Am Freitag, 23. November 2012 09:35:48 UTC+1 schrieb DeadMG:

> Except that's impossible to implement, because depending on TUs and what's
> declared, the size required changes.

How come MSVC implements it exactly that way?

--




------=_Part_167_172249.1353660223686
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Am Freitag, 23. November 2012 09:35:48 UTC+1 schrieb DeadMG:<br><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">Except that's impossible to implement, be=
cause depending on TUs and what's declared, the size required changes.</blo=
ckquote><div>How come MSVC implements it exactly that way?&nbsp;</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_167_172249.1353660223686--

.


Author: stackmachine@hotmail.com
Date: Fri, 23 Nov 2012 00:51:42 -0800 (PST)
Raw View
------=_Part_245_1774615.1353660702963
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Am Freitag, 23. November 2012 09:41:30 UTC+1 schrieb Nicol Bolas:

>
>
> On Thursday, November 22, 2012 11:13:36 PM UTC-8, stackm...@hotmail.comwr=
ote:
>>
>> Actually, let me take this a step further. C++ violatates its own=20
>> principle (don't pay for what you don't use) by implicitly requiring=20
>> pointers to members to be of the same size. (5.2.10.10)
>>
>>> =20
>>>    -=20
>>>   =20
>>>    =97  converting a prvalue of type =93pointer to member function=94 t=
o a=20
>>>    different pointer to member function type and back to its original t=
ype=20
>>>    yields the original pointer to member value.=20
>>>     -=20
>>>   =20
>>>    =97  converting a prvalue of type =93pointer to data member of X of =
type T1=94=20
>>>    to the type =93pointer to data member of Y of type T2=94 (where the=
=20
>>>    alignment requirements of T2 are no stricter than those of T1) and=
=20
>>>    back to its original type yields the original pointer to member valu=
e.=20
>>>   =20
>>> I'm not sure I see how that's paying for something you don't use any=20
> more than having structs that have alignment padding.
>
Depending on the class hierarchy, base-offsets might be required. However,=
=20
in the case of a class without inheritance, this is unneeded. C++ requires=
=20
all types of pointers to be of the same size, no matter what the class=20
hierarchy looks like.  GCC implements this correctly, all member pointers=
=20
are 16 bytes in size. 8 Bytes are unused.

--=20




------=_Part_245_1774615.1353660702963
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Am Freitag, 23. November 2012 09:41:30 UTC+1 schrieb Nicol Bolas:<br><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><br>On Thursday, November 22, 20=
12 11:13:36 PM UTC-8, <a>stackm...@hotmail.com</a> wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">Actually, let me take this a step further. C++ viola=
tates its own principle (don't pay for what you don't use) by implicitly re=
quiring pointers to members to be of the same size. (5.2.10.10)<div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-=
left:1ex">
 =09
=09
=09
  <div>
   <ul style=3D"list-style-type:none">
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to member function=94 to a dif=
ferent pointer to member function
type and back to its original type yields the original pointer to member va=
lue.
</span></p>
    </li>
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to data member of </span><span=
 style=3D"font-size:10.000000pt;font-family:'LMMono10'">X </span><span styl=
e=3D"font-size:10.000000pt;font-family:'LMRoman10'">of type </span><span st=
yle=3D"font-size:10.000000pt;font-family:'LMMono10'">T1=94 </span><span sty=
le=3D"font-size:10.000000pt;font-family:'LMRoman10'">to the type =93pointer=
 to data
member of </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10=
'">Y </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">o=
f type </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10'">=
T2=94 </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=
(where the alignment requirements of </span><span style=3D"font-size:10.000=
000pt;font-family:'LMMono10'">T2 </span><span style=3D"font-size:10.000000p=
t;font-family:'LMRoman10'">are no stricter than those of </span><span style=
=3D"font-size:10.000000pt;font-family:'LMMono10'">T1)
</span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">and ba=
ck to its original type yields the original pointer to member value.&nbsp;<=
/span></p></li></ul></div></blockquote><div></div></div></blockquote><div>I=
'm not sure I see how that's paying for something you don't use any more th=
an having structs that have alignment padding.</div></blockquote><div>Depen=
ding on the class hierarchy, base-offsets might be required. However, in th=
e case of a class without inheritance, this is unneeded. C++ requires all t=
ypes of pointers to be of the same size, no matter what the class hierarchy=
 looks like. &nbsp;GCC implements this correctly, all member pointers are 1=
6 bytes in size. 8 Bytes are unused.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_245_1774615.1353660702963--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 01:00:29 -0800 (PST)
Raw View
------=_Part_215_24666971.1353661229116
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Friday, November 23, 2012 12:51:43 AM UTC-8, stackm...@hotmail.com wrote=
:
>
> Am Freitag, 23. November 2012 09:41:30 UTC+1 schrieb Nicol Bolas:
>
>>
>>
>> On Thursday, November 22, 2012 11:13:36 PM UTC-8, stackm...@hotmail.comw=
rote:
>>>
>>> Actually, let me take this a step further. C++ violatates its own=20
>>> principle (don't pay for what you don't use) by implicitly requiring=20
>>> pointers to members to be of the same size. (5.2.10.10)
>>>
>>>> =20
>>>>    -=20
>>>>   =20
>>>>    =97  converting a prvalue of type =93pointer to member function=94 =
to a=20
>>>>    different pointer to member function type and back to its original =
type=20
>>>>    yields the original pointer to member value.=20
>>>>     -=20
>>>>   =20
>>>>    =97  converting a prvalue of type =93pointer to data member of X of=
=20
>>>>    type T1=94 to the type =93pointer to data member of Y of type T2=94=
 (where=20
>>>>    the alignment requirements of T2 are no stricter than those of T1) =
and=20
>>>>    back to its original type yields the original pointer to member val=
ue.=20
>>>>   =20
>>>> I'm not sure I see how that's paying for something you don't use any=
=20
>> more than having structs that have alignment padding.
>>
> Depending on the class hierarchy, base-offsets might be required. However=
,=20
> in the case of a class without inheritance, this is unneeded. C++ require=
s=20
> all types of pointers to be of the same size, no matter what the class=20
> hierarchy looks like.
>

It most certainly does not. C++ only requires that *certain* casts are=20
meaningful and reversible. It doesn't require pointers to classes to be=20
convertible to pointers to integers and back. It doesn't require pointers=
=20
to functions to be convertible to pointers to classes and back.

More importantly, this doesn't answer my question: how does having=20
differently sized member pointers equate to paying for something you don't=
=20
use?
=20

>  GCC implements this correctly, all member pointers are 16 bytes in size.=
=20
> 8 Bytes are unused.
>

The spec is the arbiter of "correct", and if Visual Studio allows those=20
operations that the specification says work to actually work, then it is=20
just as "correct" as GCC.

--=20




------=_Part_215_24666971.1353661229116
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<br><br>On Friday, November 23, 2012 12:51:43 AM UTC-8, stackm...@hotmail.c=
om wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Am Freitag, 23. Novem=
ber 2012 09:41:30 UTC+1 schrieb Nicol Bolas:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><br><br>On Thursday, November 22, 2012 11:13:36 PM UTC-8, <a>s=
tackm...@hotmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Actu=
ally, let me take this a step further. C++ violatates its own principle (do=
n't pay for what you don't use) by implicitly requiring pointers to members=
 to be of the same size. (5.2.10.10)<div><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:r=
gb(204,204,204);border-left-style:solid;padding-left:1ex">
 =09
=09
=09
  <div>
   <ul style=3D"list-style-type:none">
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to member function=94 to a dif=
ferent pointer to member function
type and back to its original type yields the original pointer to member va=
lue.
</span></p>
    </li>
    <li>
     <p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=97 &=
nbsp;converting a prvalue of type =93pointer to data member of </span><span=
 style=3D"font-size:10.000000pt;font-family:'LMMono10'">X </span><span styl=
e=3D"font-size:10.000000pt;font-family:'LMRoman10'">of type </span><span st=
yle=3D"font-size:10.000000pt;font-family:'LMMono10'">T1=94 </span><span sty=
le=3D"font-size:10.000000pt;font-family:'LMRoman10'">to the type =93pointer=
 to data
member of </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10=
'">Y </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">o=
f type </span><span style=3D"font-size:10.000000pt;font-family:'LMMono10'">=
T2=94 </span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">=
(where the alignment requirements of </span><span style=3D"font-size:10.000=
000pt;font-family:'LMMono10'">T2 </span><span style=3D"font-size:10.000000p=
t;font-family:'LMRoman10'">are no stricter than those of </span><span style=
=3D"font-size:10.000000pt;font-family:'LMMono10'">T1)
</span><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'">and ba=
ck to its original type yields the original pointer to member value.&nbsp;<=
/span></p></li></ul></div></blockquote><div></div></div></blockquote><div>I=
'm not sure I see how that's paying for something you don't use any more th=
an having structs that have alignment padding.</div></blockquote><div>Depen=
ding on the class hierarchy, base-offsets might be required. However, in th=
e case of a class without inheritance, this is unneeded. C++ requires all t=
ypes of pointers to be of the same size, no matter what the class hierarchy=
 looks like.</div></blockquote><div><br>It most certainly does not. C++ onl=
y requires that <i>certain</i> casts are meaningful and reversible. It does=
n't require pointers to classes to be convertible to pointers to integers a=
nd back. It doesn't require pointers to functions to be convertible to poin=
ters to classes and back.<br><br>More importantly, this doesn't answer my q=
uestion: how does having differently sized member pointers equate to paying=
 for something you don't use?<br>&nbsp;</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div> &nbsp;GCC implements this correctly, all member pointe=
rs are 16 bytes in size. 8 Bytes are unused.</div></blockquote><div><br>The=
 spec is the arbiter of "correct", and if Visual Studio allows those operat=
ions that the specification says work to actually work, then it is just as =
"correct" as GCC.<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_215_24666971.1353661229116--

.


Author: stackmachine@hotmail.com
Date: Fri, 23 Nov 2012 03:01:05 -0800 (PST)
Raw View
------=_Part_2_31113138.1353668465490
Content-Type: text/plain; charset=ISO-8859-1



Am Freitag, 23. November 2012 10:00:29 UTC+1 schrieb Nicol Bolas:
>
> It most certainly does not. C++ only requires that *certain* casts are
> meaningful and reversible. It doesn't require pointers to classes to be
> convertible to pointers to integers and back. It doesn't require pointers
> to functions to be convertible to pointers to classes and back.
>
What I actually meaned to say was: "C++ requires all data member pointers
to be of same size as well as all member function pointers."


> More importantly, this doesn't answer my question: how does having
> differently sized member pointers equate to paying for something you don't
> use?
>
 I said, requiring them to be of the same size means to pay for something i
don't use.


>  GCC implements this correctly, all member pointers are 16 bytes in size.
>> 8 Bytes are unused.
>>
>
> The spec is the arbiter of "correct", and if Visual Studio allows those
> operations that the specification says work to actually work, then it is
> just as "correct" as GCC.
>
It is impossible to do that with different sizes. It causes loss of data
when converted from a large to a smaller pointer. That's why MSVC doesn't
allow these casts.

--




------=_Part_2_31113138.1353668465490
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>Am Freitag, 23. November 2012 10:00:29 UTC+1 schrieb Nicol Bolas:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div>It most certainly does not.=
 C++ only requires that <i>certain</i> casts are meaningful and reversible.=
 It doesn't require pointers to classes to be convertible to pointers to in=
tegers and back. It doesn't require pointers to functions to be convertible=
 to pointers to classes and back.<br></div></blockquote><div>What I actuall=
y meaned to say was: "C++ requires all data member pointers to be of same s=
ize as well as all member function pointers."</div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div>More importantly, this doesn't a=
nswer my question: how does having differently sized member pointers equate=
 to paying for something you don't use?<br></div></blockquote><div>&nbsp;I =
said, requiring them to be of the same size means to pay for something i do=
n't use.</div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div> &nbsp;GCC impleme=
nts this correctly, all member pointers are 16 bytes in size. 8 Bytes are u=
nused.</div></blockquote><div><br>The spec is the arbiter of "correct", and=
 if Visual Studio allows those operations that the specification says work =
to actually work, then it is just as "correct" as GCC.<br></div></blockquot=
e><div>It is impossible to do that with different sizes. It causes loss of =
data when converted from a large to a smaller pointer. That's why MSVC does=
n't allow these casts.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_2_31113138.1353668465490--

.


Author: stackmachine@hotmail.com
Date: Wed, 28 Nov 2012 21:47:55 -0800 (PST)
Raw View
------=_Part_539_12175389.1354168075168
Content-Type: text/plain; charset=ISO-8859-1

*bump*

--




------=_Part_539_12175389.1354168075168
Content-Type: text/html; charset=ISO-8859-1

*bump*

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_539_12175389.1354168075168--

.