Topic: Mini-proposal: Alignment helpers


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 19 Aug 2014 21:11:59 -0700 (PDT)
Raw View
------=_Part_3833_1754481320.1408507919883
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I took the alignment bits out of my larger bitwise operations proposal and=
=20
want to submit them separately as they are sort of self-contained and not=
=20
really related to bitwise operations.

The draft is here:
https://github.com/fmatthew5876/stdcxx-align

Does anyone have any reason why these should not be part of the standard=20
library?

Here is feedback from the initial bitops paper, I'll address the alignment=
=20
comments below.
https://issues.isocpp.org/show_bug.cgi?id=3D37

doesn't handle the lack of implicit conversion to/from void*...


Not sure I completely understand the question, but I will attempt to answer=
..


Any T* will convert to void* so you can call any of the functions on any po=
inter type. The result will be a void* and this will require a cast if you =
want to convert it back up to a T*. I think requiring casts here makes sens=
e because if you are manually aligning blocks of memory you are most likely=
 operating in a place outside of the type system.


Another option would be to provide templated overloads for all pointers, li=
ke this:


template <typename T>

constexpr T* align_down(T* p, size_t align) noexcept;


I'm not sure if that's a better interface. I don't believe its unsafe, beca=
use assuming the input T* has an alignment of at least alignof(T), the resu=
lt of align_up() or align_down() cannot produce a pointer whose alignment i=
s less than alignof(T).


also problem on machines that aren't byte-addressible.


I'm not sure this is really a problem. Anyone writing simd code, encryption=
 code, device drivers, etc.. would

already need to account for how the machine they are working on can be addr=
essed and handle it themselves. None of these functions actually dereferenc=
e a pointer so they cannot trigger hardware errors related to byte addressa=
bility directly.=20


Also as stated earlier, neither align_up() or align_down() can produce a po=
inter with an alignment less than

the input. Therefore if we had a hypothetical 2 byte addressable machine, I=
 think it would be safe to assume all pointers we receive by normal means w=
ould be at least 2 byte aligned and therefore this API would not produce an=
y invalid pointers for those cases.



Thanks

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_3833_1754481320.1408507919883
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I took the alignment bits out of my larger bitwise operati=
ons proposal and want to submit them separately as they are sort of self-co=
ntained and not really related to bitwise operations.<div><br></div><div>Th=
e draft is here:</div><div>https://github.com/fmatthew5876/stdcxx-align<br>=
</div><div><br></div><div>Does anyone have any reason why these should not =
be part of the standard library?</div><div><br></div><div>Here is feedback =
from the initial bitops paper, I'll address the alignment comments below.</=
div><div>https://issues.isocpp.org/show_bug.cgi?id=3D37<br></div><div><br><=
/div><div><pre class=3D"bz_comment_text" style=3D"font-size: medium; white-=
space: pre-wrap; width: 50em; color: rgb(0, 0, 0);">doesn't handle the lack=
 of implicit conversion to/from void*...</pre><pre class=3D"bz_comment_text=
" style=3D"font-size: medium; white-space: pre-wrap; width: 50em; color: rg=
b(0, 0, 0);"><br></pre><pre class=3D"bz_comment_text" style=3D"font-size: m=
edium; white-space: pre-wrap; width: 50em; color: rgb(0, 0, 0);"><span styl=
e=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica, sans-serif; fon=
t-size: 13px;">Not sure I completely understand the question, but I will at=
tempt to answer.</span></pre><pre class=3D"bz_comment_text" style=3D"font-s=
ize: medium; white-space: pre-wrap; width: 50em; color: rgb(0, 0, 0);"><spa=
n style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica, sans-seri=
f; font-size: 13px;"><br></span></pre><pre class=3D"bz_comment_text" style=
=3D"font-size: medium; white-space: pre-wrap; width: 50em; color: rgb(0, 0,=
 0);"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica,=
 sans-serif; font-size: 13px;">Any T* will convert to void* so you can call=
 any of the functions on any pointer type. The result will be a void* and t=
his will require a cast if you want to convert it back up to a T*. I think =
requiring casts here makes sense because if you are manually aligning block=
s of memory you are most likely operating in a place outside of the type sy=
stem.</span></pre><pre class=3D"bz_comment_text" style=3D"font-size: medium=
; white-space: pre-wrap; width: 50em; color: rgb(0, 0, 0);"><span style=3D"=
color: rgb(34, 34, 34); font-family: Arial, Helvetica, sans-serif; font-siz=
e: 13px;"><br></span></pre><pre class=3D"bz_comment_text" style=3D"font-siz=
e: medium; white-space: pre-wrap; width: 50em; color: rgb(0, 0, 0);"><span =
style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica, sans-serif;=
 font-size: 13px;">Another option would be to provide templated overloads f=
or all pointers, like this:</span></pre><pre class=3D"bz_comment_text" styl=
e=3D"font-size: medium; white-space: pre-wrap; width: 50em; color: rgb(0, 0=
, 0);"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica=
, sans-serif; font-size: 13px;"><br></span></pre><pre class=3D"bz_comment_t=
ext" style=3D"font-size: medium; white-space: pre-wrap; width: 50em; color:=
 rgb(0, 0, 0);"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, =
Helvetica, sans-serif; font-size: 13px;">template &lt;typename T&gt;</span>=
</pre><pre class=3D"bz_comment_text" style=3D"white-space: pre-wrap; width:=
 50em;"><font face=3D"Arial, Helvetica, sans-serif">constexpr T* align_down=
(T* p, size_t align) noexcept;</font></pre><pre class=3D"bz_comment_text" s=
tyle=3D"white-space: pre-wrap; width: 50em;"><br></pre><pre class=3D"bz_com=
ment_text" style=3D"white-space: pre-wrap; width: 50em;"><font face=3D"Aria=
l, Helvetica, sans-serif">I'm not sure if that's a better interface. I don'=
t believe its unsafe, because assuming the input T* has an alignment of at =
least alignof(T), the result of align_up() or align_down() cannot produce a=
 pointer whose alignment is less than alignof(T).</font></pre><pre class=3D=
"bz_comment_text" style=3D"font-size: medium; white-space: pre-wrap; width:=
 50em; color: rgb(0, 0, 0);"><br></pre><pre class=3D"bz_comment_text" style=
=3D"font-size: medium; white-space: pre-wrap; width: 50em; color: rgb(0, 0,=
 0);">also problem on machines that aren't byte-addressible.</pre><pre clas=
s=3D"bz_comment_text" style=3D"font-size: medium; white-space: pre-wrap; wi=
dth: 50em; color: rgb(0, 0, 0);"><br></pre><pre class=3D"bz_comment_text" s=
tyle=3D"width: 50em; white-space: pre-wrap;"><pre class=3D"bz_comment_text"=
 style=3D"color: rgb(0, 0, 0); font-size: medium; white-space: pre-wrap; wi=
dth: 50em;"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helv=
etica, sans-serif; font-size: 13px;">I'm not sure this is really a problem.=
 Anyone writing simd code, encryption code, device drivers, etc.. would</sp=
an></pre><pre class=3D"bz_comment_text" style=3D"color: rgb(0, 0, 0); font-=
size: medium; white-space: pre-wrap; width: 50em;"><span style=3D"color: rg=
b(34, 34, 34); font-family: Arial, Helvetica, sans-serif; font-size: 13px;"=
>already need to account for how the machine they are working on can be add=
ressed and handle it themselves. None of these functions actually dereferen=
ce a pointer so they cannot trigger hardware errors related to byte address=
ability directly.&nbsp;</span></pre><pre class=3D"bz_comment_text" style=3D=
"color: rgb(0, 0, 0); font-size: medium; white-space: pre-wrap; width: 50em=
;"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica, sa=
ns-serif; font-size: 13px;"><br></span></pre><pre class=3D"bz_comment_text"=
 style=3D"color: rgb(0, 0, 0); font-size: medium; white-space: pre-wrap; wi=
dth: 50em;"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helv=
etica, sans-serif; font-size: 13px;">Also as stated&nbsp;earlier, neither a=
lign_up() or align_down() can produce a pointer with an alignment less than=
</span></pre><pre class=3D"bz_comment_text" style=3D"color: rgb(0, 0, 0); f=
ont-size: medium; white-space: pre-wrap; width: 50em;"><span style=3D"color=
: rgb(34, 34, 34); font-family: Arial, Helvetica, sans-serif; font-size: 13=
px;">the input. Therefore if we had a hypothetical 2 byte addressable machi=
ne, I think it would be safe to assume all pointers we receive by normal me=
ans would be at least 2 byte aligned and therefore this API would not produ=
ce any invalid pointers for those cases.</span></pre><pre class=3D"bz_comme=
nt_text" style=3D"color: rgb(0, 0, 0); font-size: medium; white-space: pre-=
wrap; width: 50em;"><br></pre><pre class=3D"bz_comment_text" style=3D"color=
: rgb(0, 0, 0); font-size: medium; white-space: pre-wrap; width: 50em;"><br=
></pre><pre class=3D"bz_comment_text" style=3D"color: rgb(0, 0, 0); font-si=
ze: medium; white-space: pre-wrap; width: 50em;"><span style=3D"color: rgb(=
34, 34, 34); font-family: Arial, Helvetica, sans-serif; font-size: 13px;">T=
hanks</span></pre></pre></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_3833_1754481320.1408507919883--

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 20 Aug 2014 13:06:56 +0800
Raw View
--Apple-Mail=_F4DF7D1C-641B-4315-87B4-55F409475307
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-08-20, at 12:11 PM, Matthew Fioravante <fmatthew5876@gmail.com> wro=
te:

> I took the alignment bits out of my larger bitwise operations proposal an=
d want to submit them separately as they are sort of self-contained and not=
 really related to bitwise operations.
>=20
> The draft is here:
> https://github.com/fmatthew5876/stdcxx-align
>=20
> Does anyone have any reason why these should not be part of the standard =
library?

There might not be much interest. GCC still doesn't have std::align (https:=
//gcc.gnu.org/bugzilla/show_bug.cgi?id=3D57350). I'm apparently the only pe=
rson ever to have "complained," but not because I actually use that functio=
n. MSVC has an implementation, but it had bugs as of last year (http://stac=
koverflow.com/q/16305311/153285) and I don't know whether it's currently co=
rrect. Clang (libc++) has had std::align since before C++11, originally as =
a nonconforming extension and perhaps it was the original prototype. Its im=
plementation assumes that size_t is the same as uintptr_t.

You cited the Linux kernel as an example, but it's not written in C++. Pers=
onally I've written that sort of SIMD code but I tend to do such arithmetic=
 on indexes, not pointers. Just IMHO, some anecdotes or testimonials might =
help your case. Feel free to use my buggy initial submission at the GCC bug=
 page to illustrate how implementation can go wrong :v) .

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_F4DF7D1C-641B-4315-87B4-55F409475307
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;08&ndash;20, at 12:11 PM, Matthew Fioravante &lt;<a href=3D"mailto:fm=
atthew5876@gmail.com">fmatthew5876@gmail.com</a>&gt; wrote:</div><br class=
=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr">I=
 took the alignment bits out of my larger bitwise operations proposal and w=
ant to submit them separately as they are sort of self-contained and not re=
ally related to bitwise operations.<div><br></div><div>The draft is here:</=
div><div><a href=3D"https://github.com/fmatthew5876/stdcxx-align">https://g=
ithub.com/fmatthew5876/stdcxx-align</a><br></div><div><br></div><div>Does a=
nyone have any reason why these should not be part of the standard library?=
</div></div></blockquote><div><br></div><div>There might not be much intere=
st. GCC still doesn&rsquo;t have <font face=3D"Courier">std::align</font> (=
<a href=3D"https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D57350">https://gc=
c.gnu.org/bugzilla/show_bug.cgi?id=3D57350</a>). I&rsquo;m apparently the o=
nly person ever to have &ldquo;complained,&rdquo; but not because I actuall=
y use that function. MSVC has an implementation, but it had bugs as of last=
 year (<a href=3D"http://stackoverflow.com/q/16305311/153285">http://stacko=
verflow.com/q/16305311/153285</a>) and I don&rsquo;t know whether it&rsquo;=
s currently correct. Clang (libc++) has had <font face=3D"Courier">std::ali=
gn</font>&nbsp;since before C++11, originally as a nonconforming extension =
and perhaps it was the original prototype. Its implementation assumes that&=
nbsp;<font face=3D"Courier">size_t</font> is the same as <font face=3D"Cour=
ier">uintptr_t</font>.</div><div><br></div><div>You cited the Linux kernel =
as an example, but it&rsquo;s not written in C++. Personally I&rsquo;ve wri=
tten that sort of SIMD code but I tend to do such arithmetic on indexes, no=
t pointers. Just IMHO, some anecdotes or testimonials might help your case.=
 Feel free to use my buggy initial submission at the GCC bug page to illust=
rate how implementation can go wrong :v) .</div></div><br></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_F4DF7D1C-641B-4315-87B4-55F409475307--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 20 Aug 2014 05:03:24 -0700 (PDT)
Raw View
------=_Part_43_1394655173.1408536204557
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, August 20, 2014 1:07:18 AM UTC-4, David Krauss wrote:
>
> You cited the Linux kernel as an example, but it=E2=80=99s not written in=
 C++.=20
>

I'm not sure that matters. I'm sure we would all love to see an operating=
=20
system kernel or device drivers written in C++.
=20

> Personally I=E2=80=99ve written that sort of SIMD code but I tend to do s=
uch=20
> arithmetic on indexes, not pointers.=20
>

Even if you use indexes, you still need to determine which index is the=20
first one which is aligned so that you can start using the aligned simd=20
loads.
=20

> Just IMHO, some anecdotes or testimonials might help your case.=20
>

Yes, I probably need more examples outside of only the linux kernel.
=20

> Feel free to use my buggy initial submission at the GCC bug page to=20
> illustrate how implementation can go wrong :v) .
>

Indeed highlighting how implementations can go wrong in subtle non-obvious=
=20
ways greatly bolsters the argument for standardization. I'll look into=20
this.=20

Thanks for your feedback!

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_43_1394655173.1408536204557
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, August 20, 2014 1:07:18 AM UTC-4, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D=
"word-wrap:break-word"><div>You cited the Linux kernel as an example, but i=
t=E2=80=99s not written in C++. </div></div></blockquote><div><br></div><di=
v>I'm not sure that matters. I'm sure we would all love to see an operating=
 system kernel or device drivers written in C++.</div><div>&nbsp;</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word=
"><div><div>Personally I=E2=80=99ve written that sort of SIMD code but I te=
nd to do such arithmetic on indexes, not pointers. </div></div></div></bloc=
kquote><div><br></div><div>Even if you use indexes, you still need to deter=
mine which index is the first one which is aligned so that you can start us=
ing the aligned simd loads.</div><div>&nbsp;</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><div>Just IMHO=
, some anecdotes or testimonials might help your case. </div></div></div></=
blockquote><div><br></div><div>Yes, I probably need more examples outside o=
f only the linux kernel.</div><div>&nbsp;</div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><div>Feel free to=
 use my buggy initial submission at the GCC bug page to illustrate how impl=
ementation can go wrong :v) .</div></div></div></blockquote><div><br></div>=
<div>Indeed highlighting how implementations can go wrong in subtle non-obv=
ious ways greatly bolsters the argument for standardization. I'll look into=
 this.&nbsp;</div><div><br></div><div>Thanks for your feedback!</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_43_1394655173.1408536204557--

.


Author: Myriachan <myriachan@gmail.com>
Date: Wed, 20 Aug 2014 16:15:32 -0700 (PDT)
Raw View
------=_Part_60_659899022.1408576532843
Content-Type: text/plain; charset=UTF-8

On Wednesday, August 20, 2014 5:03:24 AM UTC-7, Matthew Fioravante wrote:
....

I have some feedback of my own:

 * Your implementation assumes a flat address space.  As far as I
understand, nothing in the C or C++ standard states that for any char *x, reinterpret_cast<char
*>(reinterpret_cast<std::uintptr_t>(x) + 1) == x + 1.  Again, as far as I
understand, it would be legal for an C or C++ implementation to have
casting to uintptr_t be encrypting with Triple-DES and casting from
uintptr_t be decrypting with Triple-DES.  Your specification should be
defined in terms of how each function affects alignment, not the
mathematics each function executes.  In this regard, align_up and align_down
sort of have a definition that works if worded correctly.  The mathematics
should just be regarded as a "potential implementation for an environment
with a flat address space in which arithmetic on std::uintptr_t is
equivalent to the same arithmetic on char *, and reinterpret_cast<std::uintptr_t>(nullptr)
== 0".

 * There should be a note that using these functions with intptr_t or
uintptr_t is *not* the same thing as using these functions with pointers,
for the above reason.  (Unless there's a flat address space, but the
Standard need not mention this.)

 * I would add the following warnings:
The result of align_up or align_down with parameters of object pointer type
is undefined if there does not exist a *safely-derived pointer* that meets
the requirements. [* Note:* That is, that the aligned version of the
pointer would be before the beginning of the memory block allocated for the
object or array of objects, or after one past the end of that memory block. *--
end note* ]

 * I think adding a template for arbitrarily-typed pointers would be a good
idea, so long as it takes precautions so that only object pointers can be
passed, and not member pointers or function pointers.  However, if you do
this, make the align parameter have a default value of alignof(T) for
convenience.  void and its *cv*-qualified versions would need to be
template specializations or overloads (I don't know which is better in this
case).

 * Editorial: Your "Implementation:" sections use the variable "a" when the
function is declared as using the name "align".

Open question: Should the functions be required to support passing a value
larger than PTRDIFF_MAX as "align"?  It is, in fact, possible to reach this
situation on certain platforms; for example, in 32-bit Windows programs
running on 64-bit Windows.

Melissa

--

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

------=_Part_60_659899022.1408576532843
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 20, 2014 5:03:24 AM UTC-7, Matthew Fi=
oravante wrote:<br><div>...<br><br>I have some feedback of my own:<br><br>&=
nbsp;* Your implementation assumes a flat address space.&nbsp; As far as I =
understand, nothing in the C or C++ standard states that for any <span styl=
e=3D"font-family: courier new,monospace;">char *x</span>, <span style=3D"fo=
nt-family: courier new,monospace;">reinterpret_cast&lt;char *&gt;(reinterpr=
et_cast&lt;std::uintptr_t&gt;(x) + 1) =3D=3D x + 1</span>.&nbsp; Again, as =
far as I understand, it would be legal for an C or C++ implementation to ha=
ve casting to <span style=3D"font-family: courier new,monospace;">uintptr_t=
</span> be encrypting with Triple-DES and casting from <span style=3D"font-=
family: courier new,monospace;">uintptr_t</span> be decrypting with Triple-=
DES.&nbsp; Your specification should be defined in terms of how each functi=
on affects alignment, not the mathematics each function executes.&nbsp; In =
this regard, <span style=3D"font-family: courier new,monospace;">align_up</=
span> and <span style=3D"font-family: courier new,monospace;">align_down</s=
pan> sort of have a definition that works if worded correctly.&nbsp; The ma=
thematics should just be regarded as a "potential implementation for an env=
ironment with a flat address space in which arithmetic on <span style=3D"fo=
nt-family: courier new,monospace;">std::uintptr_t</span> is equivalent to t=
he same arithmetic on <span style=3D"font-family: courier new,monospace;">c=
har *<font face=3D"arial,sans-serif">, and <span style=3D"font-family: cour=
ier new,monospace;">reinterpret_cast&lt;std::uintptr_t&gt;(nullptr) =3D=3D =
0</span></font></span>".<br><br>&nbsp;* There should be a note that using t=
hese functions with <span style=3D"font-family: courier new,monospace;">int=
ptr_t</span> or <span style=3D"font-family: courier new,monospace;">uintptr=
_t</span> is <i>not</i> the same thing as using these functions with pointe=
rs, for the above reason.&nbsp; (Unless there's a flat address space, but t=
he Standard need not mention this.)<br><br>&nbsp;* I would add the followin=
g warnings:<br>The result of align_up or align_down with parameters of obje=
ct pointer type is undefined if there does not exist a <i>safely-derived po=
inter</i> that meets the requirements. [<i> Note:</i> That is, that the ali=
gned version of the pointer would be before the beginning of the memory blo=
ck allocated for the object or array of objects, or after one past the end =
of that memory block. <i>-- end note</i> ]<br><br>&nbsp;* I think adding a =
template for arbitrarily-typed pointers would be a good idea, so long as it=
 takes precautions so that only object pointers can be passed, and not memb=
er pointers or function pointers.&nbsp; However, if you do this, make the <=
span style=3D"font-family: courier new,monospace;">align</span> parameter h=
ave a default value of <span style=3D"font-family: courier new,monospace;">=
alignof(T)</span> for convenience.&nbsp; <span style=3D"font-family: courie=
r new,monospace;">void</span> and its <i>cv</i>-qualified versions would ne=
ed to be template specializations or overloads (I don't know which is bette=
r in this case).<br><br>&nbsp;* Editorial: Your "Implementation:" sections =
use the variable "a" when the function is declared as using the name "<span=
 style=3D"font-family: courier new,monospace;">align</span>".<br><br>Open q=
uestion: Should the functions be required to support passing a value larger=
 than PTRDIFF_MAX as "<span style=3D"font-family: courier new,monospace;">a=
lign</span>"?&nbsp; It is, in fact, possible to reach this situation on cer=
tain platforms; for example, in 32-bit Windows programs running on 64-bit W=
indows.<br><br>Melissa<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_60_659899022.1408576532843--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 20 Aug 2014 18:29:41 -0500
Raw View
On Wednesday 20 August 2014 16:15:32 Myriachan wrote:
> Open question: Should the functions be required to support passing a value
> larger than PTRDIFF_MAX as "align"?  It is, in fact, possible to reach this
> situation on certain platforms; for example, in 32-bit Windows programs
> running on 64-bit Windows.

It is theoretically possible for that to exist, but not on the platform you
listed. A 32-bit windows application has 32-bit pointers, regardless of the
OS. PTRDIFF_MAX is the same as INT_MAX.

A platform with segmented memory could do that, like 16-bit DOS and Windows
were for the large memory model.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 21 Aug 2014 07:41:02 +0800
Raw View
--Apple-Mail=_37F9B024-3A53-4F48-BC18-845A05B1F212
Content-Type: text/plain; charset=ISO-8859-1


On 2014-08-21, at 7:29 AM, Thiago Macieira <thiago@macieira.org> wrote:

> It is theoretically possible for that to exist, but not on the platform you
> listed. A 32-bit windows application has 32-bit pointers, regardless of the
> OS. PTRDIFF_MAX is the same as INT_MAX.
>
> A platform with segmented memory could do that, like 16-bit DOS and Windows
> were for the large memory model.

Still, there should be some stated requirements to guarantee that the result is valid, such as that the beginning and end of the allocation block containing the argument pointer have the specified alignment.

Also, unless the suggested implementations are truly universal, it might be better to leave them out of the spec. Melissa is right that reinterpret_cast<uintptr_t> is allowed to do any random transformation, as long as it's reversible.

--

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

--Apple-Mail=_37F9B024-3A53-4F48-BC18-845A05B1F212
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;08&ndash;21, at 7:29 AM, Thiago Macieira &lt;<a href=3D"mailto:thiago=
@macieira.org">thiago@macieira.org</a>&gt; wrote:</div><br class=3D"Apple-i=
nterchange-newline"><blockquote type=3D"cite">It is theoretically possible =
for that to exist, but not on the platform you <br>listed. A 32-bit windows=
 application has 32-bit pointers, regardless of the <br>OS. PTRDIFF_MAX is =
the same as INT_MAX.<br><br>A platform with segmented memory could do that,=
 like 16-bit DOS and Windows <br>were for the large memory model.<br></bloc=
kquote><br></div><div>Still, there should be some stated requirements to gu=
arantee that the result is valid, such as that the beginning and end of the=
 allocation block containing the argument pointer have the specified alignm=
ent.</div><br><div>Also, unless the suggested implementations are truly uni=
versal, it might be better to leave them out of the spec. Melissa is right =
that <font face=3D"Courier">reinterpret_cast&lt;uintptr_t&gt;</font>&nbsp;i=
s allowed to do any random transformation, as long as it&rsquo;s reversible=
..</div><div><br></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_37F9B024-3A53-4F48-BC18-845A05B1F212--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 20 Aug 2014 22:38:58 -0500
Raw View
On Thursday 21 August 2014 07:41:02 David Krauss wrote:
> On 2014-08-21, at 7:29 AM, Thiago Macieira <thiago@macieira.org> wrote:
> > It is theoretically possible for that to exist, but not on the platform
> > you
> > listed. A 32-bit windows application has 32-bit pointers, regardless of
> > the
> > OS. PTRDIFF_MAX is the same as INT_MAX.
> >
> > A platform with segmented memory could do that, like 16-bit DOS and
> > Windows
> > were for the large memory model.
>
> Still, there should be some stated requirements to guarantee that the result
> is valid, such as that the beginning and end of the allocation block
> containing the argument pointer have the specified alignment.

ptrdiff is only valid for two pointers referring to the same array. You're not
officially allowed to use it on two unrelated pointers. In practice, we do that
all of the time, but it wouldn't work on a segmented, large memory model
application.

So the requirement here should be the same: the user will have to guarantee
that the alignment operation won't under- or overflow the array containing the
pointer or the memory block as created by malloc() or new[].

In practice, align_down of any power of two up to PAGE_SIZE on modern
architectures will return a valid, readable pointer that will not cause a
crash. For doing SIMD code, that is an interesting operation, so I'd like this
underflow to be implementation-defined behaviour, as opposed to undefined
behaviour. Overflowing the buffer can be undefined behaviour.

> Also, unless the suggested implementations are truly universal, it might be
> better to leave them out of the spec. Melissa is right that
> reinterpret_cast<uintptr_t> is allowed to do any random transformation, as
> long as it's reversible.

Agreed. State the requirement, but like she said list the code for example
purposes only and let the compiler developers figure out how to do it for their
platform.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 20 Aug 2014 20:55:57 -0700 (PDT)
Raw View
------=_Part_146_62888504.1408593357992
Content-Type: text/plain; charset=UTF-8

Hi everyone! This has been some very valuable feedback. Thank you for
taking the time to read the paper.


On Wednesday, August 20, 2014 7:15:33 PM UTC-4, Myriachan wrote:
>
>
>  * I think adding a template for arbitrarily-typed pointers would be a
> good idea, so long as it takes precautions so that only object pointers can
> be passed, and not member pointers or function pointers.  However, if you
> do this, make the align parameter have a default value of alignof(T) for
> convenience.
>

Not sure I see the intention here?

If you have:
T* align_up(T* p, size_t a = alignof(T));
T* align_down(T* p, size_t a = alignof(T));
bool is_aligned(T* p, size_t a = alignof(T));

Then it should always be the case that

T* p = something;
p == align_up(p) == align_down(p);
true == is_aligned(p);

Do you have a specific use case where you think the typed versions with
defaults would be helpful? I'm more inclined to leave them out as we
usually are dealing with untyped memory when we need to reach for alignment
macros. Also std::align() only operates on void*.

I'm really not strong on either direction though. We can have the T*
variants if people think they are useful.


> void and its *cv*-qualified versions would need to be template
> specializations or overloads (I don't know which is better in this case).
>

Usually overloading is preffered, specialization can have some gotchas.
http://stackoverflow.com/questions/7108033/template-specialization-vs-function-overloading


On Wednesday, August 20, 2014 11:39:34 PM UTC-4, Thiago Macieira wrote:
>
> On Thursday 21 August 2014 07:41:02 David Krauss wrote:
> > On 2014-08-21, at 7:29 AM, Thiago Macieira <thi...@macieira.org
> <javascript:>> wrote:
> > > It is theoretically possible for that to exist, but not on the
> platform
> > > you
> > > listed. A 32-bit windows application has 32-bit pointers, regardless
> of
> > > the
> > > OS. PTRDIFF_MAX is the same as INT_MAX.
> > >
> > > A platform with segmented memory could do that, like 16-bit DOS and
> > > Windows
> > > were for the large memory model.
> >
> > Still, there should be some stated requirements to guarantee that the
> result
> > is valid, such as that the beginning and end of the allocation block
> > containing the argument pointer have the specified alignment.
>
> ptrdiff is only valid for two pointers referring to the same array. You're
> not
> officially allowed to use it on two unrelated pointers. In practice, we do
> that
> all of the time, but it wouldn't work on a segmented, large memory model
> application.
>
> So the requirement here should be the same: the user will have to
> guarantee
> that the alignment operation won't under- or overflow the array containing
> the
> pointer or the memory block as created by malloc() or new[].
>
> In practice, align_down of any power of two up to PAGE_SIZE on modern
> architectures will return a valid, readable pointer that will not cause a
> crash. For doing SIMD code, that is an interesting operation, so I'd like
> this
> underflow to be implementation-defined behaviour, as opposed to undefined
> behaviour. Overflowing the buffer can be undefined behaviour.
>

Why not implementation defined for both? You might want to do an
align_up(x, PAGE_SIZE) to find the upper bound of the page. Is there really
a practical difference between choosing UB vs IB here outside of standard
wording?

--

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

------=_Part_146_62888504.1408593357992
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi everyone! This has been some very valuable feedbac=
k. Thank you for taking the time to read the paper.</div><br><br>On Wednesd=
ay, August 20, 2014 7:15:33 PM UTC-4, Myriachan wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; bo=
rder-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left=
: 1ex;"><div dir=3D"ltr"><br></div></blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-l=
eft-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;=
"><div dir=3D"ltr">&nbsp;* I think adding a template for arbitrarily-typed =
pointers would be a good idea, so long as it takes precautions so that only=
 object pointers can be passed, and not member pointers or function pointer=
s.&nbsp; However, if you do this, make the&nbsp;<span style=3D"font-family:=
 'courier new', monospace;">align</span>&nbsp;parameter have a default valu=
e of&nbsp;<span style=3D"font-family: 'courier new', monospace;">alignof(T)=
</span>&nbsp;for convenience.&nbsp;&nbsp;</div></blockquote><div><br></div>=
<div>Not sure I see the intention here?</div><div><br></div><div>If you hav=
e:</div><div>T* align_up(T* p, size_t a =3D alignof(T));</div><div>T* align=
_down(T* p, size_t a =3D alignof(T));</div><div>bool is_aligned(T* p, size_=
t a =3D alignof(T));</div><div><br></div><div>Then it should always be the =
case that</div><div><br></div><div>T* p =3D something;</div><div>p =3D=3D a=
lign_up(p) =3D=3D align_down(p);</div><div>true =3D=3D is_aligned(p);</div>=
<div><br></div><div>Do you have a specific use case where you think the typ=
ed versions with defaults would be helpful? I'm more inclined to leave them=
 out as we usually are dealing with untyped memory when we need to reach fo=
r alignment macros. Also std::align() only operates on void*.</div><div><br=
></div><div>I'm really not strong on either direction though. We can have t=
he T* variants if people think they are useful.</div><div>&nbsp;</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: sol=
id; padding-left: 1ex;"><div dir=3D"ltr"><span style=3D"font-family: 'couri=
er new', monospace;">void</span>&nbsp;and its&nbsp;<i>cv</i>-qualified vers=
ions would need to be template specializations or overloads (I don't know w=
hich is better in this case).<br></div></blockquote><div><br></div><div>Usu=
ally overloading is preffered, specialization can have some gotchas.</div><=
div>http://stackoverflow.com/questions/7108033/template-specialization-vs-f=
unction-overloading<br></div><div><br></div><br>On Wednesday, August 20, 20=
14 11:39:34 PM UTC-4, Thiago Macieira wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">On Thursday 21 August 2014 07:41:02 David Krauss wrote:
<br>&gt; On 2014-08-21, at 7:29 AM, Thiago Macieira &lt;<a href=3D"javascri=
pt:" target=3D"_blank" gdf-obfuscated-mailto=3D"r07T2ME6MvMJ" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">thi...@macieira.org</a>&gt; wrote:
<br>&gt; &gt; It is theoretically possible for that to exist, but not on th=
e platform
<br>&gt; &gt; you
<br>&gt; &gt; listed. A 32-bit windows application has 32-bit pointers, reg=
ardless of
<br>&gt; &gt; the
<br>&gt; &gt; OS. PTRDIFF_MAX is the same as INT_MAX.
<br>&gt; &gt;=20
<br>&gt; &gt; A platform with segmented memory could do that, like 16-bit D=
OS and
<br>&gt; &gt; Windows
<br>&gt; &gt; were for the large memory model.
<br>&gt;=20
<br>&gt; Still, there should be some stated requirements to guarantee that =
the result
<br>&gt; is valid, such as that the beginning and end of the allocation blo=
ck
<br>&gt; containing the argument pointer have the specified alignment.
<br>
<br>ptrdiff is only valid for two pointers referring to the same array. You=
're not=20
<br>officially allowed to use it on two unrelated pointers. In practice, we=
 do that=20
<br>all of the time, but it wouldn't work on a segmented, large memory mode=
l=20
<br>application.=20
<br>
<br>So the requirement here should be the same: the user will have to guara=
ntee=20
<br>that the alignment operation won't under- or overflow the array contain=
ing the=20
<br>pointer or the memory block as created by malloc() or new[].
<br>
<br>In practice, align_down of any power of two up to PAGE_SIZE on modern=
=20
<br>architectures will return a valid, readable pointer that will not cause=
 a=20
<br>crash. For doing SIMD code, that is an interesting operation, so I'd li=
ke this=20
<br>underflow to be implementation-defined behaviour, as opposed to undefin=
ed=20
<br>behaviour. Overflowing the buffer can be undefined behaviour.
<br></blockquote><div><br></div><div>Why not implementation defined for bot=
h? You might want to do an align_up(x, PAGE_SIZE) to find the upper bound o=
f the page. Is there really a practical difference between choosing UB vs I=
B here outside of standard wording?</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_146_62888504.1408593357992--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 00:02:41 -0500
Raw View
On Wednesday 20 August 2014 20:55:57 Matthew Fioravante wrote:
> Not sure I see the intention here?
>
> If you have:
> T* align_up(T* p, size_t a = alignof(T));
> T* align_down(T* p, size_t a = alignof(T));
> bool is_aligned(T* p, size_t a = alignof(T));

Please make the three functions take void* and/or char* as the first argument,
not a T*. That necessarily implies the template argument is required in
calling the function.

Is the compiler allowed to have a different bitwise representation for a T*
compared to a void*? More to the point, could a T* representation simply not
contain the bits of the misalignment? Or put another way, are you allowed to
load a misaligned void* pointer onto a T*?

> > In practice, align_down of any power of two up to PAGE_SIZE on modern
> > architectures will return a valid, readable pointer that will not cause a
> > crash. For doing SIMD code, that is an interesting operation, so I'd like
> > this
> > underflow to be implementation-defined behaviour, as opposed to undefined
> > behaviour. Overflowing the buffer can be undefined behaviour.
>
> Why not implementation defined for both? You might want to do an
> align_up(x, PAGE_SIZE) to find the upper bound of the page. Is there really
> a practical difference between choosing UB vs IB here outside of standard
> wording?

That's also fine. What's important for me is that align_down *not* be UB.
Though people have to understand that aligning up might result in
unrepresentable pointers (e.g., align_up of PAGE_SIZE on the last addressable
page, 2*PAGE_SIZE on the second-to-last addressable page, etc). On the other
hand, I can't think of a platform where align_down of any power of 2 could
result in an unrepresentable pointer.

The practical difference is that IB code is valid, as long as you respect the
rules defined by the particular platform and compiler, whichever they are. An
UB is invalid, period:

 struct S {
  int 4;  // aligned to 4
  char c; // aligned to 4
  char buf[15]; // 1 byte past aligned to 4
 } s;

 double *d = align_down<double>(s.buf, alignof(d)); // definitely UB
 // any code here is under UB and the compiler can defrost my fridge

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Myriachan <myriachan@gmail.com>
Date: Wed, 20 Aug 2014 23:31:31 -0700 (PDT)
Raw View
------=_Part_173_1873155646.1408602691911
Content-Type: text/plain; charset=UTF-8



On Wednesday, August 20, 2014 10:02:48 PM UTC-7, Thiago Macieira wrote:
>
> On Wednesday 20 August 2014 20:55:57 Matthew Fioravante wrote:
> > Not sure I see the intention here?
> >
> > If you have:
> > T* align_up(T* p, size_t a = alignof(T));
> > T* align_down(T* p, size_t a = alignof(T));
> > bool is_aligned(T* p, size_t a = alignof(T));
>
> Please make the three functions take void* and/or char* as the first
> argument,
> not a T*. That necessarily implies the template argument is required in
> calling the function.
>

You're right; I like your definition *much* better.  There wouldn't need to
be a char * or unsigned char * version with a void * version, so void * is
fine.

template <typename T> T *align_up(void *p, size_t a = alignof(T));
void *align_up(void *p, size_t a);
template <typename T> T *align_down(void *p, size_t a = alignof(T));
void *align_down(void *p, size_t a);
template <typename T> bool is_aligned(void *p, size_t a = alignof(T));
bool is_aligned(void *p, size_t a);

(And const/volatile/const volatile equivalents thereof.  This would be a
bit tricky, possibly requiring std::enable_if in order to prohibit passing
a non-const type T to the void * overload...?  Otherwise, you could violate
const-correctness easily)


>
> Is the compiler allowed to have a different bitwise representation for a
> T*
> compared to a void*? More to the point, could a T* representation simply
> not
> contain the bits of the misalignment? Or put another way, are you allowed
> to
> load a misaligned void* pointer onto a T*?
>

I'm very new to this, but I think the compiler is allowed to do that for
any pointer type except char * and unsigned char *.  Like my Triple-DES
example >.<


> > > In practice, align_down of any power of two up to PAGE_SIZE on modern
> > > architectures will return a valid, readable pointer that will not
> cause a
> > > crash. For doing SIMD code, that is an interesting operation, so I'd
> like
> > > this
> > > underflow to be implementation-defined behaviour, as opposed to
> undefined
> > > behaviour. Overflowing the buffer can be undefined behaviour.
> >
> > Why not implementation defined for both? You might want to do an
> > align_up(x, PAGE_SIZE) to find the upper bound of the page. Is there
> really
> > a practical difference between choosing UB vs IB here outside of
> standard
> > wording?
>
> That's also fine. What's important for me is that align_down *not* be UB.
> Though people have to understand that aligning up might result in
> unrepresentable pointers (e.g., align_up of PAGE_SIZE on the last
> addressable
> page, 2*PAGE_SIZE on the second-to-last addressable page, etc). On the
> other
> hand, I can't think of a platform where align_down of any power of 2 could
> result in an unrepresentable pointer.
>

It's always been undefined behavior, though, to produce a pointer that is
outside the bounds of its original allocation.  Aligning downward higher
than the original allocation alignment can easily do this.

Implementations can be a verifiably-safe environment, where programs are
sandboxed, because pointers can never take on values that are not valid
allocated memory.  There is, in fact, one such C++ implementation in Lua,
apparently.  I don't remember its name or the level of its compatibility,
though.

I feel as though the Standard ought to define various *memory models* and
have #defines for them to indicate to a program its environment.  The
memory models we're used to are "flat" and "segmented".  These would be my
definitions of the types:

Shared among "flat" and "segmented":
1. Object pointers are bitwise-identical in memory.  That is, these two
cases result in identical values of cp and p for all object pointers T *
provided other requirements are met (not that you could pun them; that's an
aliasing violation):

// Shared
union { unsigned char *cp; T *p; } u;
// Case 1
u.p = a;
u.p += b;
// Case 2
u.cp = a;
u.cp += b * sizeof(T);

2. The bitwise representation of nullptr cast to object pointer type is
identical to nullptr cast to std::uintptr_t and std::intptr_t.
(Establishing zero point for the next point.)

3. Casting a pointer to std::[u]intptr_t, performing integer arithmetic on
it, then casting back, is equivalent to performing the same arithmetic on
the pointer cast to char *, if the pointer remains *safely-derived*.

4. Comparing two pointers cast to std::[u]intptr_t returns the same result
as comparing the original pointers if the pointer comparison's result is
*specified*.  (The term "undefined" is not used in the Standard for
unrelated pointer comparisons; "unspecified" or "not specified" is.  I
supposed a compiler causing your code to do anything with a bad pointer
comparison other than have a true or false result of arbitrary useless
meaning is against the Standard, unlike, say, signed integer overflow.)

Flat memory spaces require removing #3's restriction that the pointer
remain *safely-derived*, but *using* that pointer, of course, is undefined
if not.

The practical difference is that IB code is valid, as long as you respect
> the
> rules defined by the particular platform and compiler, whichever they are.
> An
> UB is invalid, period:
>
>         struct S {
>                 int 4;                // aligned to 4
>                 char c;        // aligned to 4
>                 char buf[15]; // 1 byte past aligned to 4
>         } s;
>
>         double *d = align_down<double>(s.buf, alignof(d)); // definitely
> UB
>         // any code here is under UB and the compiler can defrost my
> fridge
>

(Assuming the "int 4" was a typo.)  How is this undefined behavior on any
platform where alignof(double) <= 4 (e.g. 32-bit Windows, PlayStation 2)?
I think it is actually implementation-defined here, because s.buf decays to char
*, which is allowed to alias anything.  S is a *standard-layout* type.  The
elements therefore must go in order, and one byte before s.buf must be
either s.c or padding before s.buf.  If it's padding, then it's going to
work because there's nothing in the padding.  With s.c also being type char,
and a char * being around, aliasing rules shouldn't apply.

At least, this is how I read it.  I could be very wrong, though!

Melissa

--

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

------=_Part_173_1873155646.1408602691911
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, August 20, 2014 10:02:48 PM UTC-7, T=
hiago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wednes=
day 20 August 2014 20:55:57 Matthew Fioravante wrote:
<br>&gt; Not sure I see the intention here?
<br>&gt;=20
<br>&gt; If you have:
<br>&gt; T* align_up(T* p, size_t a =3D alignof(T));
<br>&gt; T* align_down(T* p, size_t a =3D alignof(T));
<br>&gt; bool is_aligned(T* p, size_t a =3D alignof(T));
<br>
<br>Please make the three functions take void* and/or char* as the first ar=
gument,=20
<br>not a T*. That necessarily implies the template argument is required in=
=20
<br>calling the function.
<br></blockquote><div><br>You're right; I like your definition <i>much</i> =
better.&nbsp; There wouldn't need to be a <span style=3D"font-family: couri=
er new,monospace;">char *</span> or <span style=3D"font-family: courier new=
,monospace;">unsigned char *</span> version with a <span style=3D"font-fami=
ly: courier new,monospace;">void *</span> version, so <span style=3D"font-f=
amily: courier new,monospace;">void *</span> is fine.<br><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> T </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">align_up</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><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: #000;" class=3D"styled-by-prettify">p</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> size_t a </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">alignof</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">));</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=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: #6=
60;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">align_up</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">p</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> size_t a</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">template</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> T </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">align_down</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</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">p</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> size_t a </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">align=
of</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><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-b=
y-prettify">align_down</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">p</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> size_t a</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 style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> is_aligned</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #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">p</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> size_t a </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">alignof</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">T</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 style=3D"color: #008;=
" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> is_aligned</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"sty=
led-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">p</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> size_t a</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>=
(And <span style=3D"font-family: courier new,monospace;">const</span>/<span=
 style=3D"font-family: courier new,monospace;">volatile</span>/<span style=
=3D"font-family: courier new,monospace;">const volatile</span> equivalents =
thereof.&nbsp; This would be a bit tricky, possibly requiring <span style=
=3D"font-family: courier new,monospace;">std::enable_if</span> in order to =
prohibit passing a non-<span style=3D"font-family: courier new,monospace;">=
const</span> type <span style=3D"font-family: courier new,monospace;">T</sp=
an> to the <span style=3D"font-family: courier new,monospace;">void *</span=
> overload...?&nbsp; Otherwise, you could violate <span style=3D"font-famil=
y: courier new,monospace;">const</span>-correctness easily)<br>&nbsp;</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">
<br>Is the compiler allowed to have a different bitwise representation for =
a T*=20
<br>compared to a void*? More to the point, could a T* representation simpl=
y not=20
<br>contain the bits of the misalignment? Or put another way, are you allow=
ed to=20
<br>load a misaligned void* pointer onto a T*?
<br></blockquote><div><br>I'm very new to this, but I think the compiler is=
 allowed to do that for any pointer type except <span style=3D"font-family:=
 courier new,monospace;">char *</span> and <span style=3D"font-family: cour=
ier new,monospace;">unsigned char *</span>.&nbsp; Like my Triple-DES exampl=
e &gt;.&lt;<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt=
; &gt; In practice, align_down of any power of two up to PAGE_SIZE on moder=
n
<br>&gt; &gt; architectures will return a valid, readable pointer that will=
 not cause a
<br>&gt; &gt; crash. For doing SIMD code, that is an interesting operation,=
 so I'd like
<br>&gt; &gt; this
<br>&gt; &gt; underflow to be implementation-defined behaviour, as opposed =
to undefined
<br>&gt; &gt; behaviour. Overflowing the buffer can be undefined behaviour.
<br>&gt;=20
<br>&gt; Why not implementation defined for both? You might want to do an
<br>&gt; align_up(x, PAGE_SIZE) to find the upper bound of the page. Is the=
re really
<br>&gt; a practical difference between choosing UB vs IB here outside of s=
tandard
<br>&gt; wording?
<br>
<br>That's also fine. What's important for me is that align_down *not* be U=
B.=20
<br>Though people have to understand that aligning up might result in=20
<br>unrepresentable pointers (e.g., align_up of PAGE_SIZE on the last addre=
ssable=20
<br>page, 2*PAGE_SIZE on the second-to-last addressable page, etc). On the =
other=20
<br>hand, I can't think of a platform where align_down of any power of 2 co=
uld=20
<br>result in an unrepresentable pointer.
<br></blockquote><div><br>It's always been undefined behavior, though, to p=
roduce a pointer that is outside the bounds of its original allocation.&nbs=
p; Aligning downward higher than the original allocation alignment can easi=
ly do this.<br><br>Implementations can be a verifiably-safe environment, wh=
ere programs are sandboxed, because pointers can never take on values that =
are not valid allocated memory.&nbsp; There is, in fact, one such C++ imple=
mentation in Lua, apparently.&nbsp; I don't remember its name or the level =
of its compatibility, though.<br><br>I feel as though the Standard ought to=
 define various <i>memory models</i> and have <span style=3D"font-family: c=
ourier new,monospace;">#define</span>s for them to indicate to a program it=
s environment.&nbsp; The memory models we're used to are "flat" and "segmen=
ted".&nbsp; These would be my definitions of the types:<br><br>Shared among=
 "flat" and "segmented":<br>1. Object pointers are bitwise-identical in mem=
ory.&nbsp; That is, these two cases result in identical values of <span sty=
le=3D"font-family: courier new,monospace;">cp</span> and <span style=3D"fon=
t-family: courier new,monospace;">p</span> for all object pointers <span st=
yle=3D"font-family: courier new,monospace;">T *</span> provided other requi=
rements are met (not that you could pun them; that's an aliasing violation)=
:<br><br>// Shared<br>union { unsigned char *cp; T *p; } u;<br>// Case 1<br=
>u.p =3D a;<br>u.p +=3D b;<br>// Case 2<br>u.cp =3D a;<br>u.cp +=3D b * siz=
eof(T);<br><br>2. The bitwise representation of <span style=3D"font-family:=
 courier new,monospace;">nullptr</span> cast to object pointer type is iden=
tical to <span style=3D"font-family: courier new,monospace;">nullptr</span>=
 cast to <span style=3D"font-family: courier new,monospace;">std::uintptr_t=
</span> and <span style=3D"font-family: courier new,monospace;">std::intptr=
_t</span>.&nbsp; (Establishing zero point for the next point.)<br><br>3. Ca=
sting a pointer to <span style=3D"font-family: courier new,monospace;">std:=
:<span style=3D"font-family: arial,sans-serif;">[</span>u<span style=3D"fon=
t-family: arial,sans-serif;">]</span>intptr_t</span>, performing integer ar=
ithmetic on it, then casting back, is equivalent to performing the same ari=
thmetic on the pointer cast to char *, if the pointer remains <i>safely-der=
ived</i>.<br><br>4. Comparing two pointers cast to <span style=3D"font-fami=
ly: courier new,monospace;">std::<span style=3D"font-family: arial,sans-ser=
if;">[</span>u<span style=3D"font-family: arial,sans-serif;">]</span>intptr=
_t</span> returns the same result as comparing the original pointers if the=
 pointer comparison's result is <i>specified</i>.&nbsp; (The term "undefine=
d" is not used in the Standard for unrelated pointer comparisons; "unspecif=
ied" or "not specified" is.&nbsp; I supposed a compiler causing your code t=
o do anything with a bad pointer comparison other than have a <span style=
=3D"font-family: courier new,monospace;">true</span> or <span style=3D"font=
-family: courier new,monospace;">false</span> result of arbitrary useless m=
eaning is against the Standard, unlike, say, signed integer overflow.)<br><=
br>Flat memory spaces require removing #3's restriction that the pointer re=
main <i>safely-derived</i>, but <i>using</i> that pointer, of course, is un=
defined if not.<br><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">T=
he practical difference is that IB code is valid, as long as you respect th=
e=20
<br>rules defined by the particular platform and compiler, whichever they a=
re. An=20
<br>UB is invalid, period:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct S {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;int 4;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// aligned to 4
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;char c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;// aligned to 4
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;char buf[15]; // 1 byte past aligned to 4
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} s;
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double *d =3D align_dow=
n&lt;double&gt;(s.buf, alignof(d)); // definitely UB
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// any code here is und=
er UB and the compiler can defrost my fridge
<br></blockquote><br>(Assuming the "<span style=3D"font-family: courier new=
,monospace;">int 4</span>" was a typo.)&nbsp; How is this undefined behavio=
r on any platform where <span style=3D"font-family: courier new,monospace;"=
>alignof(double) &lt;=3D 4</span> (e.g. 32-bit Windows, PlayStation 2)?&nbs=
p; I think it is actually implementation-defined here, because <span style=
=3D"font-family: courier new,monospace;">s.buf</span> decays to <span style=
=3D"font-family: courier new,monospace;">char *</span>, which is allowed to=
 alias anything.&nbsp; S is a <i>standard-layout</i> type.&nbsp; The elemen=
ts therefore must go in order, and one byte before <span style=3D"font-fami=
ly: courier new,monospace;">s.buf</span> must be either <span style=3D"font=
-family: courier new,monospace;">s.c</span> or padding before <span style=
=3D"font-family: courier new,monospace;">s.buf</span>.&nbsp; If it's paddin=
g, then it's going to work because there's nothing in the padding.&nbsp; Wi=
th <span style=3D"font-family: courier new,monospace;">s.c</span> also bein=
g type <span style=3D"font-family: courier new,monospace;">char</span>, and=
 a <span style=3D"font-family: courier new,monospace;">char *</span> being =
around, aliasing rules shouldn't apply.<br><br>At least, this is how I read=
 it.&nbsp; I could be very wrong, though!<br><br>Melissa<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_173_1873155646.1408602691911--

.


Author: Myriachan <myriachan@gmail.com>
Date: Thu, 21 Aug 2014 00:02:12 -0700 (PDT)
Raw View
------=_Part_449_1906027504.1408604532313
Content-Type: text/plain; charset=UTF-8

On Wednesday, August 20, 2014 4:30:17 PM UTC-7, Thiago Macieira wrote:
>
> On Wednesday 20 August 2014 16:15:32 Myriachan wrote:
> > Open question: Should the functions be required to support passing a
> value
> > larger than PTRDIFF_MAX as "align"?  It is, in fact, possible to reach
> this
> > situation on certain platforms; for example, in 32-bit Windows programs
> > running on 64-bit Windows.
>
> It is theoretically possible for that to exist, but not on the platform
> you
> listed. A 32-bit windows application has 32-bit pointers, regardless of
> the
> OS. PTRDIFF_MAX is the same as INT_MAX.
>

In a 32-bit Windows program running under 64-bit Windows, the 32-bit
program gets essentially the entire 4 GB address space to itself.  This is
because the x86-64 NT kernel is out of the way, up in the high half of a
48-bit address space.  It is actually possible in rare cases(*) for an
exactly 0x80000000-byte allocation to succeed, yet PTRDIFF_MAX is 0x7FFFFFFF.
(That allocations may exist that blow out a std::ptrdiff_t in this manner
is why the Standard mentions that it is possible for subtracting two
safely-derived pointers from the same allocation to have an undefined
result.)  Aligning to 0x80000000 is then a meaningful operation.

32-bit Linux programs on 64-bit Linux can do the same thing:

$ cat bigalloc2.cpp
#include <climits>
#include <cstdint>
#include <cstdio>
#include <new>

int main()
{
        char *memory = new(std::nothrow) char[0x80000000u];
        std::printf("%p %#0*tx\n", memory, static_cast<int>((sizeof(std::
ptrdiff_t) * CHAR_BIT + 3) / 4), PTRDIFF_MAX);
        return 0;
}
$ g++-4.7.2 -m32 -std=c++11 bigalloc2.cpp -o bigalloc2
$ uname -m
x86_64
$ ./bigalloc2
0x77735008 0x7fffffff


(*) Rare because there is an allocation at hardcoded address
0x7FFE0000-0x7FFE0FFF, meaning the entire upper half has to be completely
free in order for a 2 GB allocation to succeed.

Melissa

--

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

------=_Part_449_1906027504.1408604532313
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 20, 2014 4:30:17 PM UTC-7, Thiago Mac=
ieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wednesday 20 Au=
gust 2014 16:15:32 Myriachan wrote:
<br>&gt; Open question: Should the functions be required to support passing=
 a value=20
<br>&gt; larger than PTRDIFF_MAX as "align"? &nbsp;It is, in fact, possible=
 to reach this=20
<br>&gt; situation on certain platforms; for example, in 32-bit Windows pro=
grams
<br>&gt; running on 64-bit Windows.
<br>
<br>It is theoretically possible for that to exist, but not on the platform=
 you=20
<br>listed. A 32-bit windows application has 32-bit pointers, regardless of=
 the=20
<br>OS. PTRDIFF_MAX is the same as INT_MAX.
<br></blockquote><div><br>In a 32-bit Windows program running under 64-bit =
Windows, the 32-bit program gets essentially the entire 4 GB address space =
to itself.&nbsp; This is because the x86-64 NT kernel is out of the way, up=
 in the high half of a 48-bit address space.&nbsp; It is actually possible =
in rare cases(*) for an exactly <span style=3D"font-family: courier new,mon=
ospace;">0x80000000</span>-byte allocation to succeed, yet <span style=3D"f=
ont-family: courier new,monospace;">PTRDIFF_MAX</span> is <span style=3D"fo=
nt-family: courier new,monospace;">0x7FFFFFFF</span>.&nbsp; (That allocatio=
ns may exist that blow out a <span style=3D"font-family: courier new,monosp=
ace;">std::ptrdiff_t</span> in this manner is why the Standard mentions tha=
t it is possible for subtracting two safely-derived pointers from the same =
allocation to have an undefined result.)&nbsp; Aligning to <span style=3D"f=
ont-family: courier new,monospace;">0x80000000</span> is then a meaningful =
operation.<br><br>32-bit Linux programs on 64-bit Linux can do the same thi=
ng:<br><br><span style=3D"font-family: courier new,monospace;">$ cat bigall=
oc2.cpp<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 2=
50, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wid=
th: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">#=
include</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;climits&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">&lt;cstdint&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&lt;cstdio&gt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #800;" class=3D"styled-by-prettify">#include</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">&lt;new&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;=
 &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">char</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">memory </spa=
n><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: #008;" class=3D"styled-by-prettify">new</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">nothrow</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: #008;" class=3D"styled-by-prettify">char</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span =
style=3D"color: #066;" class=3D"styled-by-prettify">0x80000000u</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">];</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nb=
sp; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">printf</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">"%p %#0*tx\n"</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> memory</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: #008;" cla=
ss=3D"styled-by-prettify">static_cast</span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">((</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ptrdiff_=
t</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"colo=
r: #000;" class=3D"styled-by-prettify"> CHAR_BIT </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D=
"styled-by-prettify">3</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">/</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #066;" class=3D"styled-by-prettify">4</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> PTRDIFF_MAX</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">0</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 style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span></div></code></div>$ g++-4.7.2 -m32 -std=3Dc++11 bigalloc2.=
cpp -o bigalloc2<br>$ uname -m<br>x86_64<br>$ ./bigalloc2<br>0x77735008 0x7=
fffffff<br></span><br><br>(*) Rare because there is an allocation at hardco=
ded address 0x7FFE0000-0x7FFE0FFF, meaning the entire upper half has to be =
completely free in order for a 2 GB allocation to succeed.</div><br>Melissa=
<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_449_1906027504.1408604532313--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 09:42:53 -0500
Raw View
On Wednesday 20 August 2014 23:31:31 Myriachan wrote:
> (And const/volatile/const volatile equivalents thereof.  This would be a
> bit tricky, possibly requiring std::enable_if in order to prohibit passing
> a non-const type T to the void * overload...?  Otherwise, you could violate
> const-correctness easily)

It would fail to expand and compile due to a static or reinterpret_cast that
drops the cv qualifier.

> > Is the compiler allowed to have a different bitwise representation for a
> > T*
> > compared to a void*? More to the point, could a T* representation simply
> > not
> > contain the bits of the misalignment? Or put another way, are you allowed
> > to
> > load a misaligned void* pointer onto a T*?
>
> I'm very new to this, but I think the compiler is allowed to do that for
> any pointer type except char * and unsigned char *.  Like my Triple-DES
> example >.<

I'm asking because I don't know either.

But my gut feeling is that you should never load misaligned pointers in the
first place. That's either UB or IB.

> > That's also fine. What's important for me is that align_down *not* be UB.
> > Though people have to understand that aligning up might result in
> > unrepresentable pointers (e.g., align_up of PAGE_SIZE on the last
> > addressable
> > page, 2*PAGE_SIZE on the second-to-last addressable page, etc). On the
> > other
> > hand, I can't think of a platform where align_down of any power of 2 could
> > result in an unrepresentable pointer.
>
> It's always been undefined behavior, though, to produce a pointer that is
> outside the bounds of its original allocation.  Aligning downward higher
> than the original allocation alignment can easily do this.

By the way, I think the standard requires that the first non-element be also
representable and that ptrdiff be able to get the distance to it.

But, as I said, I need aligning down to be IB not UB.

> I feel as though the Standard ought to define various *memory models* and
> have #defines for them to indicate to a program its environment.  The
> memory models we're used to are "flat" and "segmented".  These would be my
> definitions of the types:

That seems orthogonal to the current problem.

> The practical difference is that IB code is valid, as long as you respect
>
> > the
> > rules defined by the particular platform and compiler, whichever they are.
> > An
> >
> > UB is invalid, period:
> >         struct S {
> >
> >                 int 4;                // aligned to 4
> >                 char c;        // aligned to 4
> >                 char buf[15]; // 1 byte past aligned to 4
> >
> >         } s;
> >
> >         double *d = align_down<double>(s.buf, alignof(d)); // definitely
> >
> > UB
> >
> >         // any code here is under UB and the compiler can defrost my
> >
> > fridge
>
> (Assuming the "int 4" was a typo.)  How is this undefined behavior on any
> platform where alignof(double) <= 4 (e.g. 32-bit Windows, PlayStation 2)?

If we define that align_down to an address before the first element of the array
is UB, then the code above is UB.

alignof(S) == 4
offsetof(buf, S) == 5

That means the first byte of buf is always misaligned to anything higher than
1. Requesting align_down(s.buf, 8) will always return a pointer before buf. So
if we define align_down to an address before the first element of the array to
be UB, the code above is UB.

> I think it is actually implementation-defined here, because s.buf decays to
> char *, which is allowed to alias anything.  S is a *standard-layout* type.
>  The elements therefore must go in order, and one byte before s.buf must be
> either s.c or padding before s.buf.  If it's padding, then it's going to
> work because there's nothing in the padding.  With s.c also being type
> char, and a char * being around, aliasing rules shouldn't apply.
>
> At least, this is how I read it.  I could be very wrong, though!

That's what I'm asking for: I'm asking that align_down to an element before
the first element of the array be IB.

On a flat memory address space and current architectures, align_down will
always produce a representable pointer which you can compare to the original
pointer. And if the alignment value is a power of two less than or equal to
PAGE_SIZE, the pointer is even dereferenceable without a crash.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 Aug 2014 07:45:55 -0700 (PDT)
Raw View
------=_Part_71_2131617371.1408632355542
Content-Type: text/plain; charset=UTF-8


On Thursday, August 21, 2014 1:02:48 AM UTC-4, Thiago Macieira wrote:
>
>
>
> That's also fine. What's important for me is that align_down *not* be UB.
> Though people have to understand that aligning up might result in
> unrepresentable pointers (e.g., align_up of PAGE_SIZE on the last
> addressable
> page, 2*PAGE_SIZE on the second-to-last addressable page, etc). On the
> other
> hand, I can't think of a platform where align_down of any power of 2 could
> result in an unrepresentable pointer.
>

I think thats a general problem we already have with our pointer model. If
we have an array allocated in memory, a pointer is valid if it points to
any address from the beginning of the array to 1 past the end (see
5.7.5). If your pointers happen to be at the very end of the address
space, the pointer will overflow and then you're in trouble.



>
> The practical difference is that IB code is valid, as long as you respect
> the
> rules defined by the particular platform and compiler, whichever they are.
> An
> UB is invalid, period:
>

Section 5.7.5 documents pointer arithmetic as being UB when it goes out of
bounds of the original allocation. If we use IB here we have to explain why
this deserves different treatment.

I have had a simd use case (maybe this is the one you're thinking of) where
I had to align_down() a pointer and then do an aligned simd load. After the
align_down(), the pointer was pointing to a few uninitialized memory bytes
before the block started, but this didn't matter because after reading the
leading garbage bits into the simd register I masked them out.

This worked fine on x86_64 even though I may have technically been
triggering UB. Valgrind certainly complained about it. This kind of thing
can cause crashes if you cross into an unallocated or restricted memory
page but since the alignment requirements of simd are much less than
PAGE_SIZE, this cannot happen in practice.

Do we really gain anything by leaving over/underflow pointer arithmetic as
UB but enabling a back door using align_up/align_down to get IB? It seems
like technical mess to me.

Perhaps this IB exception belongs in a simd proposal with simd aligned load
functions. For example:

//undefined behavior if !is_aligned(p, alignof(simd));
//If the memory range [p, p + sizeof(simd)) does not cover at least 1 byte
of a valid memory block, the results are undefined.
//If the memory range [p, p + sizeof(simd)) only partially points to a
valid memory block, the results are implementation defined.
void simd::aligned_load(void* p);


On Thursday, August 21, 2014 2:31:32 AM UTC-4, Myriachan wrote:
>
>
> template <typename T> T *align_up(void *p, size_t a = alignof(T));
> void *align_up(void *p, size_t a);
> template <typename T> T *align_down(void *p, size_t a = alignof(T));
> void *align_down(void *p, size_t a);
> template <typename T> bool is_aligned(void *p, size_t a = alignof(T));
> bool is_aligned(void *p, size_t a);
>

Ok I see where you guys are going with this now. The typed versions are a
sort of shorthand which allows you to avoid the cast and writing alignof().
For simd this would be useful. I will also add the requirement for the
typed versions that a must be a multiple of alignof(T), otherwise UB.

There is another benefit here. Compilers often implement cast alignment
warnings, such as -Wcast-align on gcc and clang.

Doing something like:
int* x = (int*)align_up(p, alignof(int));

can trigger a cast alignment warning even though we know for sure that the
pointer is aligned properly. Developers are forced to either disable
-Wcast-align or add implementation specific macros to turn it off for this
line. The typed align_up can disable cast alignment warnings portably
within its implementation where the cast is performed.

Performing an implicit reintepret_cast is dangerous though.

This looks somewhat reasonable:
int* i;
auto* j = align_up<simd<int>>(i);

This looks totally wrong but is allowed by the new interface.

int* x;
double * d = align_up<double>(x);







> (And const/volatile/const volatile equivalents thereof. This would be a
> bit tricky, possibly requiring std::enable_if in order to prohibit
> passing a non-const type T to the void * overload...? Otherwise, you
> could violate const-correctness easily)
>

const T* does not convert to void*, only to const void*, so we are safe
here without SFINAE tricks. We will need some additional overloads

template <typename T>
const T* align_up(const void* p, size_t a = alignof(T));

Do we really need volatile overloads also?


>
>> Is the compiler allowed to have a different bitwise representation for a
>> T*
>> compared to a void*? More to the point, could a T* representation simply
>> not
>> contain the bits of the misalignment? Or put another way, are you allowed
>> to
>> load a misaligned void* pointer onto a T*?
>>
>
converting void* to T* requires a cast which I presume would do any require
bit transformations if neccessary.


--

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

------=_Part_71_2131617371.1408632355542
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br>On Thursday, August 21, 2014 1:02:48 AM UTC-4, Th=
iago Macieira wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding=
-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; =
border-left-style: solid;" class=3D"gmail_quote"><br><br>That's also fine. =
What's important for me is that align_down *not* be UB. <br>Though people h=
ave to understand that aligning up might result in <br>unrepresentable poin=
ters (e.g., align_up of PAGE_SIZE on the last addressable <br>page, 2*PAGE_=
SIZE on the second-to-last addressable page, etc). On the other <br>hand, I=
 can't think of a platform where align_down of any power of 2 could <br>res=
ult in an unrepresentable pointer.<br></blockquote><div>&nbsp;</div><div>I =
think thats a general problem we already have with our pointer model. If we=
 have an array allocated in memory,&nbsp;a pointer is valid if it points to=
 any address from the beginning of the array to&nbsp;1 past the end (see 5.=
7.5).&nbsp;If your pointers happen to be at the very end of the address spa=
ce,&nbsp;the pointer will overflow and then you're in trouble.</div><div>&n=
bsp;</div><div>&nbsp;</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; =
padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width=
: 1px; border-left-style: solid;" class=3D"gmail_quote"><br>The practical d=
ifference is that IB code is valid, as long as you respect the <br>rules de=
fined by the particular platform and compiler, whichever they are. An <br>U=
B is invalid, period:<br></blockquote><div>&nbsp;</div><div>Section 5.7.5&n=
bsp;documents pointer arithmetic as being UB when it goes out of bounds of =
the original allocation. If we use IB here we have to explain why this dese=
rves different treatment.</div><div>&nbsp;</div><div>I have had a simd use =
case (maybe this is the one you're thinking of) where I had to align_down()=
 a pointer and then do an aligned simd load. After the align_down(), the po=
inter was pointing to a few uninitialized memory bytes before the block sta=
rted, but this didn't matter because after reading the leading garbage bits=
 into the simd register I masked them out. </div><div>&nbsp;</div><div>This=
 worked fine on x86_64 even though I may have technically been triggering U=
B. Valgrind certainly&nbsp;complained about it. This kind of thing can caus=
e crashes if you cross into an unallocated or restricted memory page but si=
nce the alignment requirements of simd are much less than PAGE_SIZE, this c=
annot happen in practice.</div><div>&nbsp;</div><div>Do we really gain anyt=
hing by leaving over/underflow pointer arithmetic as UB but enabling a back=
 door using align_up/align_down to get IB? It seems like technical mess to =
me. </div><div>&nbsp;</div><div>Perhaps this IB exception belongs in a simd=
 proposal with simd aligned&nbsp;load functions. For example:</div><div>&nb=
sp;</div><div>//undefined behavior if !is_aligned(p, alignof(simd));</div><=
div>//If the memory range [p, p + sizeof(simd)) does not cover at least 1 b=
yte of a valid memory block, the results are undefined.</div><div>//If the =
memory range [p, p + sizeof(simd)) only partially points to a valid memory =
block, the results are implementation defined.</div><div>void simd::aligned=
_load(void* p); </div><div>&nbsp;</div><div><br>On Thursday, August 21, 201=
4 2:31:32 AM UTC-4, Myriachan wrote:<blockquote style=3D"margin: 0px 0px 0p=
x 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-l=
eft-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=
=3D"ltr"><div><br><div style=3D"border: 1px solid rgb(187, 187, 187); word-=
wrap: break-word; background-color: rgb(250, 250, 250);"><code><div><span s=
tyle=3D"color: rgb(0, 0, 136);">template</span><span style=3D"color: rgb(0,=
 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><span =
style=3D"color: rgb(0, 0, 136);">typename</span><span style=3D"color: rgb(0=
, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0);">&gt;</span><spa=
n style=3D"color: rgb(0, 0, 0);"> T </span><span style=3D"color: rgb(102, 1=
02, 0);">*</span><span style=3D"color: rgb(0, 0, 0);">align_up</span><span =
style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, =
136);">void</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">*</span><span style=3D"color: rgb(0, 0, 0);">=
p</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=3D"col=
or: rgb(0, 0, 0);"> size_t a </span><span style=3D"color: rgb(102, 102, 0);=
">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"col=
or: rgb(0, 0, 136);">alignof</span><span style=3D"color: rgb(102, 102, 0);"=
>(</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color:=
 rgb(102, 102, 0);">));</span><span style=3D"color: rgb(0, 0, 0);"><br></sp=
an><span style=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: =
rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">*</span><sp=
an style=3D"color: rgb(0, 0, 0);">align_up</span><span style=3D"color: rgb(=
102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 136);">void</span><s=
pan style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 1=
02, 0);">*</span><span style=3D"color: rgb(0, 0, 0);">p</span><span style=
=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);">=
 size_t a</span><span style=3D"color: rgb(102, 102, 0);">);</span><span sty=
le=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136)=
;">template</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 13=
6);">typename</span><span style=3D"color: rgb(0, 0, 0);"> T</span><span sty=
le=3D"color: rgb(102, 102, 0);">&gt;</span><span style=3D"color: rgb(0, 0, =
0);"> T </span><span style=3D"color: rgb(102, 102, 0);">*</span><span style=
=3D"color: rgb(0, 0, 0);">align_down</span><span style=3D"color: rgb(102, 1=
02, 0);">(</span><span style=3D"color: rgb(0, 0, 136);">void</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0)=
;">*</span><span style=3D"color: rgb(0, 0, 0);">p</span><span style=3D"colo=
r: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"> size_t =
a </span><span style=3D"color: rgb(102, 102, 0);">=3D</span><span style=3D"=
color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">aligno=
f</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"col=
or: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">));</sp=
an><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rg=
b(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"> </span><spa=
n style=3D"color: rgb(102, 102, 0);">*</span><span style=3D"color: rgb(0, 0=
, 0);">align_down</span><span style=3D"color: rgb(102, 102, 0);">(</span><s=
pan style=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0=
, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">*</span><span st=
yle=3D"color: rgb(0, 0, 0);">p</span><span style=3D"color: rgb(102, 102, 0)=
;">,</span><span style=3D"color: rgb(0, 0, 0);"> size_t a</span><span style=
=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(0, 0, 0);"=
><br></span><span style=3D"color: rgb(0, 0, 136);">template</span><span sty=
le=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);=
">&lt;</span><span style=3D"color: rgb(0, 0, 136);">typename</span><span st=
yle=3D"color: rgb(0, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0=
);">&gt;</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"=
color: rgb(0, 0, 136);">bool</span><span style=3D"color: rgb(0, 0, 0);"> is=
_aligned</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=
=3D"color: rgb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"=
> </span><span style=3D"color: rgb(102, 102, 0);">*</span><span style=3D"co=
lor: rgb(0, 0, 0);">p</span><span style=3D"color: rgb(102, 102, 0);">,</spa=
n><span style=3D"color: rgb(0, 0, 0);"> size_t a </span><span style=3D"colo=
r: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> </spa=
n><span style=3D"color: rgb(0, 0, 136);">alignof</span><span style=3D"color=
: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">T</span><=
span style=3D"color: rgb(102, 102, 0);">));</span><span style=3D"color: rgb=
(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);">bool</span><s=
pan style=3D"color: rgb(0, 0, 0);"> is_aligned</span><span style=3D"color: =
rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 136);">void</spa=
n><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(10=
2, 102, 0);">*</span><span style=3D"color: rgb(0, 0, 0);">p</span><span sty=
le=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);=
"> size_t a</span><span style=3D"color: rgb(102, 102, 0);">);</span><span s=
tyle=3D"color: rgb(0, 0, 0);"><br></span></div></code></div></div></div></b=
lockquote><div>&nbsp;</div><div>Ok I see where you guys are going with this=
 now. The typed versions are a sort of shorthand which allows you to avoid =
the cast and writing alignof(). For simd this would be useful. I will also =
add the requirement for the typed versions that a must be a multiple of ali=
gnof(T), otherwise UB.</div><div>&nbsp;</div><div>There is another benefit =
here. Compilers often implement cast alignment warnings, such as -Wcast-ali=
gn on gcc and clang.</div><div>&nbsp;</div><div>Doing something like:</div>=
<div>int* x =3D (int*)align_up(p, alignof(int));</div><div>&nbsp;</div><div=
>can trigger a cast alignment warning even though we know for sure that the=
 pointer is aligned properly. Developers are forced to either disable -Wcas=
t-align or add implementation specific macros to turn it off for this line.=
 The typed align_up can disable cast alignment warnings portably within its=
 implementation where the cast is performed.</div><div>&nbsp;</div><div>Per=
forming an implicit reintepret_cast is dangerous though.</div><div>&nbsp;</=
div><div>This looks somewhat&nbsp;reasonable:</div><div>int* i;</div><div>a=
uto*&nbsp;j =3D align_up&lt;simd&lt;int&gt;&gt;(i);</div><div>&nbsp;</div><=
div>This looks totally wrong but is allowed by the new interface.</div><div=
>&nbsp;</div><div>int* x;</div><div>double * d =3D align_up&lt;double&gt;(x=
);</div><div>&nbsp;</div><div>&nbsp;</div><div>&nbsp;</div><div>&nbsp;</div=
><div>&nbsp;</div><div>&nbsp;</div><blockquote style=3D"margin: 0px 0px 0px=
 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-le=
ft-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D=
"ltr"><div>(And <span style=3D"font-family: courier new,monospace;">const</=
span>/<span style=3D"font-family: courier new,monospace;">volatile</span>/<=
span style=3D"font-family: courier new,monospace;">const volatile</span> eq=
uivalents thereof.  This would be a bit tricky, possibly requiring <span st=
yle=3D"font-family: courier new,monospace;">std::enable_if</span> in order =
to prohibit passing a non-<span style=3D"font-family: courier new,monospace=
;">const</span> type <span style=3D"font-family: courier new,monospace;">T<=
/span> to the <span style=3D"font-family: courier new,monospace;">void *</s=
pan> overload...?  Otherwise, you could violate <span style=3D"font-family:=
 courier new,monospace;">const</span>-correctness easily)<br></div></div></=
blockquote><div>&nbsp;</div><div>const T*&nbsp;does not convert&nbsp;to voi=
d*, only to const void*, so we are safe here without&nbsp;SFINAE tricks. We=
 will need some additional overloads</div><div>&nbsp;</div><div>template &l=
t;typename T&gt;</div><div>const T* align_up(const void* p, size_t a =3D al=
ignof(T));</div><div>&nbsp;</div><div>Do we really need volatile overloads =
also?</div><div>&nbsp;</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex;=
 padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-widt=
h: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><=
div> </div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1e=
x; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-le=
ft-style: solid;" class=3D"gmail_quote"><br>Is the compiler allowed to have=
 a different bitwise representation for a T* <br>compared to a void*? More =
to the point, could a T* representation simply not <br>contain the bits of =
the misalignment? Or put another way, are you allowed to <br>load a misalig=
ned void* pointer onto a T*?<br></blockquote></div></blockquote><div>&nbsp;=
</div><div>converting void* to T* requires a cast which I presume would do =
any require bit transformations if neccessary. </div><div>&nbsp;</div></div=
></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_71_2131617371.1408632355542--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 09:45:47 -0500
Raw View
On Thursday 21 August 2014 00:02:12 Myriachan wrote:
>  Rare because there is an allocation at hardcoded address
> 0x7FFE0000-0x7FFE0FFF, meaning the entire upper half has to be completely
> free in order for a 2 GB allocation to succeed.

Which it usually isn't because the stack is there, growing down from the
second-to-last addressable page.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 Aug 2014 08:06:52 -0700 (PDT)
Raw View
------=_Part_160_142992381.1408633612406
Content-Type: text/plain; charset=UTF-8

The typed pointer versions could also be considered "alignment casts" and
renamed as such.

template <typename T>
T align_up_cast(void* p, size_t a=alignof(T));


char buf[4096];
__int128_t* s;

s = align_up_cast<__int128_t*>(buf);

--

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

------=_Part_160_142992381.1408633612406
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">The typed pointer versions could also be considered "align=
ment casts" and renamed as such.<br><br>template &lt;typename T&gt; <br>T a=
lign_up_cast(void* p, size_t a=3Dalignof(T));<br><br><br>char buf[4096];<br=
>__int128_t* s;<br><br>s =3D align_up_cast&lt;__int128_t*&gt;(buf);<br></di=
v>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_160_142992381.1408633612406--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 11:19:02 -0500
Raw View
On Thursday 21 August 2014 08:06:52 Matthew Fioravante wrote:
> The typed pointer versions could also be considered "alignment casts" and
> renamed as such.
>
> template <typename T>
> T align_up_cast(void* p, size_t a=alignof(T));
>
>
> char buf[4096];
> __int128_t* s;
>
> s = align_up_cast<__int128_t*>(buf);

I like that. GCC on some architectures warns about casting to a type with
stricter alignment guarantees. Such a cast operator could be known to the
compiler, which wouldn't print the warning.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 11:36:19 -0500
Raw View
On Thursday 21 August 2014 07:45:55 Matthew Fioravante wrote:
> I think thats a general problem we already have with our pointer model. If
> we have an array allocated in memory, a pointer is valid if it points to
> any address from the beginning of the array to 1 past the end (see
> 5.7.5). If your pointers happen to be at the very end of the address
> space, the pointer will overflow and then you're in trouble.

Indeed, which is why implementations don't return anything that close to the
edge of the world.

I spent half an hour yesterday trying to see if Linux could do it, but it
doesn't. The highest address that it uses is UINTPTR_MAX - N*4096 - 3. That's
the closing null character of the last entry in _environ. With a 64-bit kernel
on current x86, I got this:

(gdb) p ((char**)_environ)[114]
$7 = 0xffffdfc0 "COLUMNS=135"

(gdb) p _environ[114]
$20 = 0x7fffffffefc0 "COLUMNS=135"

From what I can tell, the last page is always intentionally left unmapped, so
no memory block could end up with 1-past-the-end wrapping back to 0x0. The
only contrived example I could find was to do align_up of 2*PAGE_SIZE, which is
unlikely to exist in the wild.

I'm sure other architectures do similar things to comply with the C and C++
standards.

> Section 5.7.5 documents pointer arithmetic as being UB when it goes out of
> bounds of the original allocation. If we use IB here we have to explain why
> this deserves different treatment.
>
> I have had a simd use case (maybe this is the one you're thinking of) where
> I had to align_down() a pointer and then do an aligned simd load. After the
> align_down(), the pointer was pointing to a few uninitialized memory bytes
> before the block started, but this didn't matter because after reading the
> leading garbage bits into the simd register I masked them out.

That's my use-case too. Either you mask them out or you use instructions like
PALIGNR that move them out.

> This worked fine on x86_64 even though I may have technically been
> triggering UB. Valgrind certainly complained about it. This kind of thing
> can cause crashes if you cross into an unallocated or restricted memory
> page but since the alignment requirements of simd are much less than
> PAGE_SIZE, this cannot happen in practice.

You can never crash an application with align_down of up to PAGE_SIZE in
modern architectures, provided you know the original pointer is valid. Now,
this doesn't have to hold for all past or future architectures, so I'm not
asking to make this behaviour defined in the standard. But it would be great if
it were IB.

> Perhaps this IB exception belongs in a simd proposal with simd aligned load
> functions. For example:

Could be.

> Do we really need volatile overloads also?

Yes, I think so. While I don't expect volatile SIMD operations, atomic might
happen often. As an example, HP PA-RISC could only do atomic operations that
were aligned to 16 bytes, so had an oversized QAtomicInt and aligned up to 16
before doing the operation. That's a use-case for volatile.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 Aug 2014 09:42:47 -0700 (PDT)
Raw View
------=_Part_594_2063004982.1408639367328
Content-Type: text/plain; charset=UTF-8

It looks like right now clang will only do -Wcast-align warnings with C
style casts but not with reinterpret_cast. Presumably because they needed a
way to allow people to ignore the warning.

With a new set of alignment casts, perhaps they can go back to re-enabling
-Wcast-align for reinterpret_cast.


--

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

------=_Part_594_2063004982.1408639367328
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">It looks like right now clang will only do -Wcast-align wa=
rnings with C style casts but not with reinterpret_cast. Presumably because=
 they needed a way to allow people to ignore the warning.<br><br>With a new=
 set of alignment casts, perhaps they can go back to re-enabling -Wcast-ali=
gn for reinterpret_cast.<br><br><br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_594_2063004982.1408639367328--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 Aug 2014 09:53:12 -0700 (PDT)
Raw View
------=_Part_413_2112192032.1408639992440
Content-Type: text/plain; charset=UTF-8



On Thursday, August 21, 2014 12:37:12 PM UTC-4, Thiago Macieira wrote:
>
>
> Yes, I think so. While I don't expect volatile SIMD operations, atomic
> might
> happen often. As an example, HP PA-RISC could only do atomic operations
> that
> were aligned to 16 bytes, so had an oversized QAtomicInt and aligned up to
> 16
> before doing the operation. That's a use-case for volatile.
>
>
Volatile is for hardware memory and/or other weird things completely
outside of the memory model. It's not sufficient for atomic operations.
Either way it could still be useful. Maybe for some kind of memory mapped
IO. It certainly doesn't hurt to support it.

--

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

------=_Part_413_2112192032.1408639992440
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, August 21, 2014 12:37:12 PM UTC-4, Th=
iago Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>Yes, I=
 think so. While I don't expect volatile SIMD operations, atomic might=20
<br>happen often. As an example, HP PA-RISC could only do atomic operations=
 that=20
<br>were aligned to 16 bytes, so had an oversized QAtomicInt and aligned up=
 to 16=20
<br>before doing the operation. That's a use-case for volatile.
<br>
<br></blockquote><div><br>Volatile is for hardware memory and/or other weir=
d things completely outside of the memory model. It's not sufficient for at=
omic operations.<br>Either way it could still be useful. Maybe for some kin=
d of memory mapped IO. It certainly doesn't hurt to support it.<br></div></=
div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_413_2112192032.1408639992440--

.


Author: Myriachan <myriachan@gmail.com>
Date: Thu, 21 Aug 2014 12:21:46 -0700 (PDT)
Raw View
------=_Part_469_1224242619.1408648906731
Content-Type: text/plain; charset=UTF-8

On Thursday, August 21, 2014 7:43:32 AM UTC-7, Thiago Macieira wrote:
>
> > I'm very new to this, but I think the compiler is allowed to do that for
> > any pointer type except char * and unsigned char *.  Like my Triple-DES
> > example >.<
>
> I'm asking because I don't know either.
>
> But my gut feeling is that you should never load misaligned pointers in
> the
> first place. That's either UB or IB.
>

I agree with that.


> > > That's also fine. What's important for me is that align_down *not* be
> UB.
> > The practical difference is that IB code is valid, as long as you
> respect
> >
> > > the
> > > rules defined by the particular platform and compiler, whichever they
> are.
> > > An
> > >
> > > UB is invalid, period:
> > >         struct S {
> > >
> > >                 int 4;                // aligned to 4
> > >                 char c;        // aligned to 4
> > >                 char buf[15]; // 1 byte past aligned to 4
> > >
> > >         } s;
> > >
> > >         double *d = align_down<double>(s.buf, alignof(d)); //
> definitely
> > >
> > > UB
> > >
> > >         // any code here is under UB and the compiler can defrost my
> > >
> > > fridge
> >
> > (Assuming the "int 4" was a typo.)  How is this undefined behavior on
> any
> > platform where alignof(double) <= 4 (e.g. 32-bit Windows, PlayStation
> 2)?
>
> If we define that align_down to an address before the first element of the
> array
> is UB, then the code above is UB.
>

The rule that would make it undefined behavior is due to the pointer
leaving the range of the allocation, not any particular array.  Because of
this structure being standard-layout, and because the type of the array
element involved is char, I'm thinking that this is actually
implementation-defined.

I think the confusion here is resulting from the difference between a
pointer leaving the bounds of a given declared type of a structure element
versus leaving the bounds of the allocation (the "dynamic type" I think
it's formally called...?).  If you do, say, new __m128[4] and then ask to align_down<__m128>(ptr,
PAGE_SIZE), the pointer is going to leave the bounds of the original
allocation.

I hope I've cleared up any confusion about what I said.  Is it your
intention that down-aligning a pointer will always work as
implementation-defined, even if it causes the pointer to end up in la-la
land, such as heap manager territory?

By the way, what happens if aligning down results in nullptr?  Doesn't that
introduce all kinds of undefined behavior suddenly, such as pointer
arithmetic issues?


On Thursday, August 21, 2014 9:42:47 AM UTC-7, Matthew Fioravante wrote:
>
> It looks like right now clang will only do -Wcast-align warnings with C
> style casts but not with reinterpret_cast. Presumably because they needed a
> way to allow people to ignore the warning.
>
> With a new set of alignment casts, perhaps they can go back to re-enabling
> -Wcast-align for reinterpret_cast.
>

Does Clang++ issue -Wcast-align warnings with casts from void * or
std::uintptr_t at all?  I mean, these alignment routines' implementations
aren't casting from a normal type, they're casting from either void * or
integer type.


Melissa

--

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

------=_Part_469_1224242619.1408648906731
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, August 21, 2014 7:43:32 AM UTC-7, Thiago Maci=
eira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; I'm very new t=
o this, but I think the compiler is allowed to do that for
<br>&gt; any pointer type except char * and unsigned char *. &nbsp;Like my =
Triple-DES
<br>&gt; example &gt;.&lt;
<br>
<br>I'm asking because I don't know either.
<br>
<br>But my gut feeling is that you should never load misaligned pointers in=
 the=20
<br>first place. That's either UB or IB.
<br></blockquote><div><br>I agree with that.<br>&nbsp;<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">
&gt; &gt; That's also fine. What's important for me is that align_down *not=
* be UB.
<br>&gt; The practical difference is that IB code is valid, as long as you =
respect
<br>&gt;=20
<br>&gt; &gt; the
<br>&gt; &gt; rules defined by the particular platform and compiler, whiche=
ver they are.
<br>&gt; &gt; An
<br>&gt; &gt;=20
<br>&gt; &gt; UB is invalid, period:
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; struct S {
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp;=20
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int 4=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// aligned to 4
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char =
c; &nbsp; &nbsp; &nbsp; &nbsp;// aligned to 4
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char =
buf[15]; // 1 byte past aligned to 4
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp;=20
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; } s;
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp;=20
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; double *d =3D align_down&lt;doubl=
e&gt;(s.buf, alignof(d)); // definitely
<br>&gt; &gt;=20
<br>&gt; &gt; UB
<br>&gt; &gt;=20
<br>&gt; &gt; &nbsp; &nbsp; &nbsp; &nbsp; // any code here is under UB and =
the compiler can defrost my
<br>&gt; &gt;=20
<br>&gt; &gt; fridge
<br>&gt;=20
<br>&gt; (Assuming the "int 4" was a typo.) &nbsp;How is this undefined beh=
avior on any
<br>&gt; platform where alignof(double) &lt;=3D 4 (e.g. 32-bit Windows, Pla=
yStation 2)?
<br>
<br>If we define that align_down to an address before the first element of =
the array=20
<br>is UB, then the code above is UB.
<br></blockquote><div><br>The rule that would make it undefined behavior is=
 due to the pointer leaving the range of the allocation, not any particular=
 array.&nbsp; Because of this structure being standard-layout, and because =
the type of the array element involved is <span style=3D"font-family: couri=
er new,monospace;">char</span>, I'm thinking that this is actually implemen=
tation-defined.<br><br>I think the confusion here is resulting from the dif=
ference between a pointer leaving the bounds of a given declared type of a =
structure element versus leaving the bounds of the allocation (the "dynamic=
 type" I think it's formally called...?).&nbsp; If you do, say, <span style=
=3D"font-family: courier new,monospace;">new __m128[4]</span> and <span sty=
le=3D"font-family: courier new,monospace;"></span>then ask to <span style=
=3D"font-family: courier new,monospace;">align_down&lt;__m128&gt;(ptr, PAGE=
_SIZE)</span>, the pointer is going to leave the bounds of the original all=
ocation.<br><br>I hope I've cleared up any confusion about what I said.&nbs=
p; Is it your intention that down-aligning a pointer will always work as im=
plementation-defined, even if it causes the pointer to end up in la-la land=
, such as heap manager territory?<br><br>By the way, what happens if aligni=
ng down results in <span style=3D"font-family: courier new,monospace;">null=
ptr</span>?&nbsp; Doesn't that introduce all kinds of undefined behavior su=
ddenly, such as pointer arithmetic issues?<br></div><br><br>On Thursday, Au=
gust 21, 2014 9:42:47 AM UTC-7, Matthew Fioravante wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr">It looks like right now clang =
will only do -Wcast-align warnings with C style casts but not with reinterp=
ret_cast. Presumably because they needed a way to allow people to ignore th=
e warning.<br><br>With a new set of alignment casts, perhaps they can go ba=
ck to re-enabling -Wcast-align for reinterpret_cast.<br></div></blockquote>=
<div><br>Does Clang++ issue <span style=3D"font-family: courier new,monospa=
ce;">-Wcast-align</span> warnings with casts from <span style=3D"font-famil=
y: courier new,monospace;">void *</span> or <span style=3D"font-family: cou=
rier new,monospace;">std::uintptr_t</span> at all?&nbsp; I mean, these alig=
nment routines' implementations aren't casting from a normal type, they're =
casting from either <span style=3D"font-family: courier new,monospace;">voi=
d *</span> or integer type.<br><br><br>Melissa<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_469_1224242619.1408648906731--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 21 Aug 2014 14:59:43 -0500
Raw View
On Thursday 21 August 2014 12:21:46 Myriachan wrote:
> I hope I've cleared up any confusion about what I said.  Is it your
> intention that down-aligning a pointer will always work as
> implementation-defined, even if it causes the pointer to end up in la-la
> land, such as heap manager territory?

Yes.

> By the way, what happens if aligning down results in nullptr?  Doesn't that
> introduce all kinds of undefined behavior suddenly, such as pointer
> arithmetic issues?

Correct. align_down(p, UINTPTR_MAX / 2 + 1) will result in nullptr.

But I don't see that as a problem, as long as it's implementation-defined. The
implementation can probably define that align_down of anything up to PAGE_SIZE
is defined, above that it's undefined. Then all it has to do is ensure that no
valid pointer exists on the first page.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 21 Aug 2014 20:44:58 -0700 (PDT)
Raw View
------=_Part_972_1612726269.1408679098923
Content-Type: text/plain; charset=UTF-8

I've greatly expanded the paper and the example header file.

https://github.com/fmatthew5876/stdcxx-align

--

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

------=_Part_972_1612726269.1408679098923
Content-Type: text/html; charset=UTF-8

I've greatly expanded the paper and the example header file.<div><br></div><div>https://github.com/fmatthew5876/stdcxx-align<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_972_1612726269.1408679098923--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 22 Aug 2014 14:52:31 +0800
Raw View
--089e0149cf60fc0e450501324747
Content-Type: text/plain; charset=UTF-8

Minor nits:

s/smallest/least/ ; s/largest/greatest/

The null pointer value does not necessarily correspond to zero or have a
representation consisting of zero bits. It could well be all ones, or
numerically exactly one on a system where that points in the middle of a
hard-wired word at address zero. (But for convention and bzero, these
aren't terrible design choices.) I don't understand why nullptr should be
considered to be aligned: alignment determines how a pointer can be used,
but nullptr can't be used for anything anyway.

--

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

--089e0149cf60fc0e450501324747
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>Minor nits:<br><br></div>s/smallest/least/ ; s/l=
argest/greatest/<br><br></div>The null pointer value does not necessarily c=
orrespond to zero or have a representation consisting of zero bits. It coul=
d well be all ones, or numerically exactly one on a system where that point=
s in the middle of a hard-wired word at address zero. (But for convention a=
nd bzero, these aren&#39;t terrible design choices.) I don&#39;t understand=
 why nullptr should be considered to be aligned: alignment determines how a=
 pointer can be used, but nullptr can&#39;t be used for anything anyway.<br=
>
<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149cf60fc0e450501324747--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 22 Aug 2014 04:58:10 -0700 (PDT)
Raw View
------=_Part_1174_218522415.1408708690932
Content-Type: text/plain; charset=UTF-8

Hi David,

It took me a while to consider how to treat nullptr and I'm not final on
this solution.

Right now I'm treating nullptr as logically 0. The reason being is that it
makes nullptr nicely pass through the interface in a logically consistent
way.

If nullptr is aligned to everything, than the least  pointer t >= nullptr
where is_aligned(t, a) is nullptr.

For normal platforms where nullptr really is 0, this behavior just falls
out from the math and doesn't require any special cases in the code.

For some weird platform where nullptr is not actually 0, this might still
be ok. I can't imagine someone will want to align_up nullptr to store some
bytes right next to it.

I'm open to changing this behavior though if someone has a reason as to why
it should be changed.

Other options:
-IB: Let the implementation decide. This could make it harder to write
portable code.
-UB: Explicitly passing in something nullptr is wrong. Interface is a
little harder to use. May save some performance on systems where nullptr !=
0 because we don't need to check it.



On Friday, August 22, 2014 2:52:33 AM UTC-4, David Krauss wrote:
>
> Minor nits:
>
> s/smallest/least/ ; s/largest/greatest/
>
> The null pointer value does not necessarily correspond to zero or have a
> representation consisting of zero bits. It could well be all ones, or
> numerically exactly one on a system where that points in the middle of a
> hard-wired word at address zero. (But for convention and bzero, these
> aren't terrible design choices.) I don't understand why nullptr should be
> considered to be aligned: alignment determines how a pointer can be used,
> but nullptr can't be used for anything anyway.
>
>

--

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

------=_Part_1174_218522415.1408708690932
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi David,&nbsp;</div><div><br></div>It took me a whil=
e to consider how to treat nullptr and I'm not final on this solution.<div>=
<br></div><div>Right now I'm treating nullptr as logically 0. The reason be=
ing is that it makes nullptr nicely pass through the interface in a logical=
ly consistent way.&nbsp;</div><div><br></div><div>If nullptr is aligned to =
everything, than the least &nbsp;pointer t &gt;=3D nullptr where is_aligned=
(t, a) is nullptr.</div><div><br></div><div><span style=3D"font-size: 13px;=
">For normal platforms where nullptr really is 0, this behavior just falls =
out from the math and doesn't require any special cases in the code.</span>=
<br></div><div><span style=3D"font-size: 13px;"><br></span></div><div><span=
 style=3D"font-size: 13px;">For some weird platform where nullptr is not ac=
tually 0, this might still be ok. I can't imagine someone will want to alig=
n_up nullptr to store some bytes right next to it.</span></div><div><span s=
tyle=3D"font-size: 13px;"><br></span></div><div><span style=3D"font-size: 1=
3px;">I'm open to changing this behavior though if someone has a reason as =
to why it should be changed.</span></div><div><span style=3D"font-size: 13p=
x;"><br></span></div><div><span style=3D"font-size: 13px;">Other options:</=
span></div><div><span style=3D"font-size: 13px;">-IB: Let the implementatio=
n decide. This could make it harder to write portable code.</span></div><di=
v><span style=3D"font-size: 13px;">-UB: Explicitly passing in something nul=
lptr is wrong. Interface is a little harder to use. May save some performan=
ce on systems where nullptr !=3D 0 because we don't need to check it.</span=
></div><div><span style=3D"font-size: 13px;"><br></span></div><div><br><br>=
On Friday, August 22, 2014 2:52:33 AM UTC-4, David Krauss wrote:<blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div>Minor nits:<br=
><br></div>s/smallest/least/ ; s/largest/greatest/<br><br></div>The null po=
inter value does not necessarily correspond to zero or have a representatio=
n consisting of zero bits. It could well be all ones, or numerically exactl=
y one on a system where that points in the middle of a hard-wired word at a=
ddress zero. (But for convention and bzero, these aren't terrible design ch=
oices.) I don't understand why nullptr should be considered to be aligned: =
alignment determines how a pointer can be used, but nullptr can't be used f=
or anything anyway.<br>
<br></div>
</blockquote></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1174_218522415.1408708690932--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 Aug 2014 18:43:11 -0700 (PDT)
Raw View
------=_Part_844_789938122.1409103791574
Content-Type: text/plain; charset=UTF-8

I've done another update. Does anyone have any more comments or feedback?
Otherwise I'm going to submit the paper.

On Friday, August 22, 2014 7:58:11 AM UTC-4, Matthew Fioravante wrote:
>
> Hi David,
>
> It took me a while to consider how to treat nullptr and I'm not final on
> this solution.
>
> Right now I'm treating nullptr as logically 0. The reason being is that it
> makes nullptr nicely pass through the interface in a logically consistent
> way.
>
> If nullptr is aligned to everything, than the least  pointer t >= nullptr
> where is_aligned(t, a) is nullptr.
>
> For normal platforms where nullptr really is 0, this behavior just falls
> out from the math and doesn't require any special cases in the code.
>
> For some weird platform where nullptr is not actually 0, this might still
> be ok. I can't imagine someone will want to align_up nullptr to store some
> bytes right next to it.
>
> I'm open to changing this behavior though if someone has a reason as to
> why it should be changed.
>
> Other options:
> -IB: Let the implementation decide. This could make it harder to write
> portable code.
> -UB: Explicitly passing in something nullptr is wrong. Interface is a
> little harder to use. May save some performance on systems where nullptr !=
> 0 because we don't need to check it.
>
>
>
> On Friday, August 22, 2014 2:52:33 AM UTC-4, David Krauss wrote:
>>
>> Minor nits:
>>
>> s/smallest/least/ ; s/largest/greatest/
>>
>> The null pointer value does not necessarily correspond to zero or have a
>> representation consisting of zero bits. It could well be all ones, or
>> numerically exactly one on a system where that points in the middle of a
>> hard-wired word at address zero. (But for convention and bzero, these
>> aren't terrible design choices.) I don't understand why nullptr should be
>> considered to be aligned: alignment determines how a pointer can be used,
>> but nullptr can't be used for anything anyway.
>>
>>

--

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

------=_Part_844_789938122.1409103791574
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I've done another update. Does anyone have any more commen=
ts or feedback? Otherwise I'm going to submit the paper.<br><br>On Friday, =
August 22, 2014 7:58:11 AM UTC-4, Matthew Fioravante wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Hi David,&nbsp;</div><di=
v><br></div>It took me a while to consider how to treat nullptr and I'm not=
 final on this solution.<div><br></div><div>Right now I'm treating nullptr =
as logically 0. The reason being is that it makes nullptr nicely pass throu=
gh the interface in a logically consistent way.&nbsp;</div><div><br></div><=
div>If nullptr is aligned to everything, than the least &nbsp;pointer t &gt=
;=3D nullptr where is_aligned(t, a) is nullptr.</div><div><br></div><div><s=
pan style=3D"font-size:13px">For normal platforms where nullptr really is 0=
, this behavior just falls out from the math and doesn't require any specia=
l cases in the code.</span><br></div><div><span style=3D"font-size:13px"><b=
r></span></div><div><span style=3D"font-size:13px">For some weird platform =
where nullptr is not actually 0, this might still be ok. I can't imagine so=
meone will want to align_up nullptr to store some bytes right next to it.</=
span></div><div><span style=3D"font-size:13px"><br></span></div><div><span =
style=3D"font-size:13px">I'm open to changing this behavior though if someo=
ne has a reason as to why it should be changed.</span></div><div><span styl=
e=3D"font-size:13px"><br></span></div><div><span style=3D"font-size:13px">O=
ther options:</span></div><div><span style=3D"font-size:13px">-IB: Let the =
implementation decide. This could make it harder to write portable code.</s=
pan></div><div><span style=3D"font-size:13px">-UB: Explicitly passing in so=
mething nullptr is wrong. Interface is a little harder to use. May save som=
e performance on systems where nullptr !=3D 0 because we don't need to chec=
k it.</span></div><div><span style=3D"font-size:13px"><br></span></div><div=
><br><br>On Friday, August 22, 2014 2:52:33 AM UTC-4, David Krauss wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>Minor nits=
:<br><br></div>s/smallest/least/ ; s/largest/greatest/<br><br></div>The nul=
l pointer value does not necessarily correspond to zero or have a represent=
ation consisting of zero bits. It could well be all ones, or numerically ex=
actly one on a system where that points in the middle of a hard-wired word =
at address zero. (But for convention and bzero, these aren't terrible desig=
n choices.) I don't understand why nullptr should be considered to be align=
ed: alignment determines how a pointer can be used, but nullptr can't be us=
ed for anything anyway.<br>
<br></div>
</blockquote></div></div></blockquote></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_844_789938122.1409103791574--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 Aug 2014 20:28:51 -0700 (PDT)
Raw View
------=_Part_4440_2023118916.1409110131762
Content-Type: text/plain; charset=UTF-8

Theres 1 more issue I'm still not entirely sure about, and that's what
overloading scheme to use for is_aligned(void*, size_t).

void* is not sufficient because you cannot convert any cv qualified T* to
void*.

A few options:

Currently, its this:
bool is_aligned(void* p, size_t a);
bool is_aligned(const void* p, size_t a);
bool is_aligned(volatile void* p, size_t a);
bool is_aligned(const volatile void* p, size_t a);

This is to allow all cv qualifier pointers and also allow implementations
to implement the different cv versions differently if it makes sense to do
so (would it ever?)

It might be sufficient to do just specify:
bool is_aligned(const volatile void* p, size_t a);

I don't think any implementation of is_aligned() would need to dereference
the pointer, so the effects of volatile will not be observed. Also by not
dreferencing, it will also not write to the address so const also applies.
Or might it be possible according to the standard?

Another option is to just use templates and a nullptr_t overload:
template <typename T>
bool is_aligned(T* p, size_t a);
bool is_aligned(nullptr_t, size_t) { return true; }

Which would you choose?

--

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

------=_Part_4440_2023118916.1409110131762
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Theres 1 more issue I'm still not entirely sure about, and=
 that's what overloading scheme to use for is_aligned(void*, size_t).<div><=
br></div><div>void* is not sufficient because you cannot convert any cv qua=
lified T* to void*.</div><div><br></div><div>A few options:</div><div><br><=
/div><div>Currently, its this:</div><div>bool is_aligned(void* p, size_t a)=
;</div><div>bool is_aligned(const void* p, size_t a);<br></div><div>bool is=
_aligned(volatile void* p, size_t a);<br></div><div>bool is_aligned(const v=
olatile void* p, size_t a);<br></div><div><br></div><div>This is to allow a=
ll cv qualifier pointers and also allow implementations to implement the di=
fferent cv versions differently if it makes sense to do so (would it ever?)=
</div><div><br></div><div>It might be sufficient to do just specify:</div><=
div>bool is_aligned(const volatile void* p, size_t a);<br></div><div><br></=
div><div>I don't think any implementation of is_aligned() would need to der=
eference the pointer, so the effects of volatile will not be observed. Also=
 by not dreferencing, it will also not write to the address so const also a=
pplies. Or might it be possible according to the standard?</div><div><br></=
div><div>Another option is to just use templates and a nullptr_t overload:<=
/div><div>template &lt;typename T&gt;</div><div>bool is_aligned(T* p, size_=
t a);</div><div>bool is_aligned(nullptr_t, size_t) { return true; }</div><d=
iv><br></div><div>Which would you choose?</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4440_2023118916.1409110131762--

.


Author: Myriachan <myriachan@gmail.com>
Date: Tue, 26 Aug 2014 21:25:43 -0700 (PDT)
Raw View
------=_Part_163_1654131664.1409113543890
Content-Type: text/plain; charset=UTF-8



On Tuesday, August 26, 2014 8:28:51 PM UTC-7, Matthew Fioravante wrote:
>
> Theres 1 more issue I'm still not entirely sure about, and that's what
> overloading scheme to use for is_aligned(void*, size_t).
>
I don't think any implementation of is_aligned() would need to dereference
> the pointer, so the effects of volatile will not be observed. Also by not
> dreferencing, it will also not write to the address so const also applies.
> Or might it be possible according to the standard?
>
> Another option is to just use templates and a nullptr_t overload:
> template <typename T>
> bool is_aligned(T* p, size_t a);
> bool is_aligned(nullptr_t, size_t) { return true; }
>
> Which would you choose?
>

I like this one I came up with:

template <class integral>
  constexpr typename enable_if<is_integral<integral>::value && !is_same<
integral, bool>::value, bool>::type
  is_aligned(integral x, size_t a) noexcept {
    return (x & (integral(a) - 1)) == 0;
  }

template <class T>
  bool is_aligned(const volatile T* p, size_t a) noexcept {
    return is_aligned(reinterpret_cast<uintptr_t>(p), a);
  }

// 'inline' is here because this is not a template, and thus would
otherwise cause ODR problems.
inline bool is_aligned(nullptr_t, size_t) noexcept {
  return true;
}




On Tuesday, August 26, 2014 6:43:11 PM UTC-7, Matthew Fioravante wrote:
>
> I've done another update. Does anyone have any more comments or feedback?
> Otherwise I'm going to submit the paper.
>

These are the things that I think should be fixed...but I'm a
layman...laywoman(?) around here so I don't really know.

Content issues:

 * std::is_integral<bool>::value is true, but "aligning" a bool would be
really weird.  I think bool should be prohibited.
 * The integral functions' preconditions should state that the behavior of
align_up is undefined if integral is a signed type and aligning up causes
an overflow in either integral or its promoted arithmetic type.
 * The integral functions' preconditions should state that the result of
align_up is 0 if integral is an unsigned type and aligning up causes an
overflow.
 * Your integral implementation assumes that the architecture is
two's-complement.  They do not work correctly on such architectures if the
type is signed.  I suggest using ~integral(a - 1) instead of -integral(a).
You can always put a note that when integral is represented as two's
complement, that can be shortened to -integral(a).
 * I would static_cast the result of the integral functions to type integral
before returning in order to avoid warnings.  This is because the result of
the expression may not be type integral--it is the promoted type, which may
be larger than integral., and may be signed even if integral is unsigned.
(Undefined overflow can't happen unless the promoted type of an unsigned
type is a signed type with exactly one more bit; is this even allowed in an
implementation?)
 * The proper wording for the "memory block" stuff I believe is to replace
the two lines with: "p is not a *safely-derived* pointer" and "The result,
if converted as if by reinterpret_cast<void *>(*result*), would not compare
equal to reinterpret_cast<void *>(q) for some safely-derived pointer q
(ignoring *cv-*qualifiers)".  My idea for this wording is from
*[basic.stc.dynamic.safety]*.


Editorial issues (i.e. minor issues like typos):

 * "Preconditions" is one word; however, see *[structure.specifications]*
for how the Standard actually defines functions.  It doesn't use this term;
rather, it uses "*Requires:*".
 * The integral version of is_aligned is missing a semicolon.
 * The void * version of is_aligned is missing ", a".
 * Use class instead of typename for declaring type template parameters as
a matter of coding style, as that is what the Standard does.
 * Your integral implementations have "<" before "template" erroneously.
 * "implementation defined" should have a dash: "implementation-defined".

 Melissa

--

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

------=_Part_163_1654131664.1409113543890
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, August 26, 2014 8:28:51 PM UTC-7, Matt=
hew Fioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>Ther=
es 1 more issue I'm still not entirely sure about, and that's what overload=
ing scheme to use for is_aligned(void*, size_t). <br></div></blockquote><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>=
I don't think any implementation of is_aligned() would need to dereference =
the pointer, so the effects of volatile will not be observed. Also by not d=
referencing, it will also not write to the address so const also applies. O=
r might it be possible according to the standard?</div><div><br></div><div>=
Another option is to just use templates and a nullptr_t overload:</div><div=
>template &lt;typename T&gt;</div><div>bool is_aligned(T* p, size_t a);</di=
v><div>bool is_aligned(nullptr_t, size_t) { return true; }</div><div><br></=
div><div>Which would you choose?</div></div></blockquote><div><br>I like th=
is one I came up with:<br><br><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">template</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> int=
egral</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> enable_if</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">is_integral</span><span styl=
e=3D"color: #080;" class=3D"styled-by-prettify">&lt;integral&gt;</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">value </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">!</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">is_same</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">integral</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">bo=
ol</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">value</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">type<br>&nbsp; is_aligned</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">integral x</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> size_t a</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> noexcept </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">integral</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">a</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: #660;" class=3D"styled-by-prettify=
">-</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span st=
yle=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: #66=
0;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><b=
r></span><span style=3D"color: #008;" class=3D"styled-by-prettify">template=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> is_aligned</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">volatile</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> p</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> size_t a</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> noexcept </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> is_aligned</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&lt;uintptr_t&gt;</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">p</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></sp=
an><span style=3D"color: #800;" class=3D"styled-by-prettify">// 'inline' is=
 here because this is not a template, and thus would otherwise cause ODR pr=
oblems.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">inline</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> is_aligned</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">nullptr_t</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> size_t</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> noexcept </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">true=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div>=
<br><br><br>On Tuesday, August 26, 2014 6:43:11 PM UTC-7, Matthew Fioravant=
e wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I've =
done another update. Does anyone have any more comments or feedback? Otherw=
ise I'm going to submit the paper.<br></div></blockquote><br>These are the =
things that I think should be fixed...but I'm a layman...laywoman(?) around=
 here so I don't really know.<br><br>Content issues:<br><br>&nbsp;* <span s=
tyle=3D"font-family: courier new,monospace;">std::is_integral&lt;bool&gt;::=
value</span> is <span style=3D"font-family: courier new,monospace;">true</s=
pan>, but "aligning" a <span style=3D"font-family: courier new,monospace;">=
bool</span> would be really weird.&nbsp; I think <span style=3D"font-family=
: courier new,monospace;">bool</span> should be prohibited.<br>&nbsp;* The =
integral functions' preconditions should state that the behavior of <span s=
tyle=3D"font-family: courier new,monospace;">align_up</span> is undefined i=
f <span style=3D"font-family: courier new,monospace;">integral</span> is a =
signed type and aligning up causes an overflow in either <span style=3D"fon=
t-family: courier new,monospace;">integral</span> or its promoted arithmeti=
c type.<br>&nbsp;* The integral functions' preconditions should state that =
the result of <span style=3D"font-family: courier new,monospace;">align_up<=
/span> is <span style=3D"font-family: courier new,monospace;">0</span> if <=
span style=3D"font-family: courier new,monospace;">integral</span> is an un=
signed type and aligning up causes an overflow.<br>&nbsp;*
 Your integral implementation assumes that the architecture is=20
two's-complement.&nbsp; They do not work correctly on such architectures if=
=20
the type is signed.&nbsp; I suggest using <span style=3D"font-family: couri=
er new,monospace;">~integral(a - 1)</span> instead of <span style=3D"font-f=
amily: courier new,monospace;">-integral(a)</span>.&nbsp; You can always pu=
t a note that when integral is represented as two's complement, that can be=
 shortened to <span style=3D"font-family: courier new,monospace;">-integral=
(a)</span>.<br>&nbsp;* I would <span style=3D"font-family: courier new,mono=
space;">static_cast</span> the result of the integral functions to type <sp=
an style=3D"font-family: courier new,monospace;">integral</span> before ret=
urning in order to avoid warnings.&nbsp; This is because the result of the =
expression may not be type <span style=3D"font-family: courier new,monospac=
e;">integral</span>--it is the promoted type, which may be larger than <spa=
n style=3D"font-family: courier new,monospace;">integral</span>.,
 and may be signed even if integral is unsigned.&nbsp; (Undefined overflow=
=20
can't happen unless the promoted type of an unsigned type is a signed=20
type with exactly one more bit; is this even allowed in an=20
implementation?)<br>&nbsp;* The proper wording for the "memory block" stuff=
 I believe is to replace the two lines with: "<span style=3D"font-family: c=
ourier new,monospace;">p</span> is not a <i>safely-derived</i> pointer" and=
 "The result, if converted as if by <span style=3D"font-family: courier new=
,monospace;">reinterpret_cast&lt;void *&gt;(</span><i>result</i><span style=
=3D"font-family: courier new,monospace;">)</span>, would not compare equal =
to <span style=3D"font-family: courier new,monospace;">reinterpret_cast&lt;=
void *&gt;(q)</span> for some safely-derived pointer <span style=3D"font-fa=
mily: courier new,monospace;">q</span> (ignoring <i>cv-</i>qualifiers)".&nb=
sp; My idea for this wording is from <b>[basic.stc.dynamic.safety]</b>.<br>=
<br><br>Editorial issues (i.e. minor issues like typos):<br><br>&nbsp;* "Pr=
econditions" is one word; however, see <b>[structure.specifications]</b> fo=
r how the Standard actually defines functions.&nbsp; It doesn't use this te=
rm; rather, it uses "<i>Requires:</i>".<br>&nbsp;* The integral version of =
<span style=3D"font-family: courier new,monospace;">is_aligned</span> is mi=
ssing a semicolon.<br>&nbsp;* The <span style=3D"font-family: courier new,m=
onospace;">void *</span> version of <span style=3D"font-family: courier new=
,monospace;">is_aligned</span> is missing "<span style=3D"font-family: cour=
ier new,monospace;">, a</span>".<br>&nbsp;* Use <span style=3D"font-family:=
 courier new,monospace;">class</span> instead of <span style=3D"font-family=
: courier new,monospace;">typename</span> for declaring type template param=
eters as a matter of coding style, as that is what the Standard does.<br>&n=
bsp;* Your integral implementations have "<span style=3D"font-family: couri=
er new,monospace;">&lt;</span>" before "<span style=3D"font-family: courier=
 new,monospace;">template</span>" erroneously.<br>&nbsp;* "implementation d=
efined" should have a dash: "implementation-defined".<br><br>&nbsp;Melissa<=
/div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_163_1654131664.1409113543890--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 26 Aug 2014 21:59:39 -0700
Raw View
On Tuesday 26 August 2014 21:25:43 Myriachan wrote:
> template <class integral>
>   constexpr typename enable_if<is_integral<integral>::value && !is_same<
> integral, bool>::value, bool>::type
>   is_aligned(integral x, size_t a) noexcept {
>     return (x & (integral(a) - 1)) == 0;
>   }
>
> template <class T>
>   bool is_aligned(const volatile T* p, size_t a) noexcept {
>     return is_aligned(reinterpret_cast<uintptr_t>(p), a);
>   }
>
> // 'inline' is here because this is not a template, and thus would
> otherwise cause ODR problems.
> inline bool is_aligned(nullptr_t, size_t) noexcept {
>   return true;
> }

I don't think we need the first one. This was about pointer alignment.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: David Krauss <potswa@gmail.com>
Date: Wed, 27 Aug 2014 14:35:51 +0800
Raw View
--Apple-Mail=_F8FAE1A3-D1EF-4A98-990F-3279AFF8F200
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-08-27, at 12:25 PM, Myriachan <myriachan@gmail.com> wrote:

>  * The proper wording for the "memory block" stuff I believe is to replac=
e the two lines with: "p is not a safely-derived pointer" and "The result, =
if converted as if by reinterpret_cast<void *>(result), would not compare e=
qual to reinterpret_cast<void *>(q) for some safely-derived pointer q (igno=
ring cv-qualifiers)".  My idea for this wording is from [basic.stc.dynamic.=
safety].

Safely-derived pointers are only safe from a garbage collector. What's impo=
rtant is that the addition operation be well-formed. In terms of [expr.add]=
 =A75.7/5, this means that the result pointer must reference the same char =
array as the argument. I think "memory block" is close enough; someone will=
 fix it if the proposal is voted in.

(By the way, the paper incorrectly cites =A75.7/5 as 5.7.5.)

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_F8FAE1A3-D1EF-4A98-990F-3279AFF8F200
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;08&ndash;27, at 12:25 PM, Myriachan &lt;<a href=3D"mailto:myriachan@g=
mail.com">myriachan@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-interc=
hange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div>&nbsp;* The =
proper wording for the "memory block" stuff I believe is to replace the two=
 lines with: "<span style=3D"font-family: courier new,monospace;">p</span> =
is not a <i>safely-derived</i> pointer" and "The result, if converted as if=
 by <span style=3D"font-family: courier new,monospace;">reinterpret_cast&lt=
;void *&gt;(</span><i>result</i><span style=3D"font-family: courier new,mon=
ospace;">)</span>, would not compare equal to <span style=3D"font-family: c=
ourier new,monospace;">reinterpret_cast&lt;void *&gt;(q)</span> for some sa=
fely-derived pointer <span style=3D"font-family: courier new,monospace;">q<=
/span> (ignoring <i>cv-</i>qualifiers)".&nbsp; My idea for this wording is =
from <b>[basic.stc.dynamic.safety]</b>.<br></div></div></blockquote><div><b=
r></div></div>Safely-derived pointers are only safe from a garbage collecto=
r. What&rsquo;s important is that the addition operation be well-formed. In=
 terms of [expr.add] =A75.7/5, this means that the result pointer must refe=
rence the same <font face=3D"Courier">char</font> array as the argument. I =
think &ldquo;memory block&rdquo; is close enough; someone will fix it if th=
e proposal is voted in.<div><br></div><div>(By the way, the paper incorrect=
ly cites =A75.7/5 as 5.7.5.)</div><div><br></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_F8FAE1A3-D1EF-4A98-990F-3279AFF8F200--

.


Author: Myriachan <myriachan@gmail.com>
Date: Wed, 27 Aug 2014 00:43:54 -0700 (PDT)
Raw View
------=_Part_6767_676575160.1409125434920
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, August 26, 2014 9:59:50 PM UTC-7, Thiago Macieira wrote:
>
> On Tuesday 26 August 2014 21:25:43 Myriachan wrote:=20
> > template <class integral>=20
> >   constexpr typename enable_if<is_integral<integral>::value && !is_same=
<=20
> > integral, bool>::value, bool>::type=20
> >   is_aligned(integral x, size_t a) noexcept {=20
> >     return (x & (integral(a) - 1)) =3D=3D 0;=20
> >   }=20
> >=20
> I don't think we need the first one. This was about pointer alignment.=20
>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>

That's fine if we want to get rid of all the integer stuff in his=20
proposal.  I just meant it as a fix for some issues that arise if we keep=
=20
it.


On Tuesday, August 26, 2014 11:36:10 PM UTC-7, David Krauss wrote:
>
>
> On 2014=E2=80=9308=E2=80=9327, at 12:25 PM, Myriachan <myri...@gmail.com>=
 wrote:
>
>  * The proper wording for the "memory block" stuff I believe is to replac=
e=20
> the two lines with: "p is not a *safely-derived* pointer" and "The=20
> result, if converted as if by reinterpret_cast<void *>(*result*), would=
=20
> not compare equal to reinterpret_cast<void *>(q) for some safely-derived=
=20
> pointer q (ignoring *cv-*qualifiers)".  My idea for this wording is from=
=20
> *[basic.stc.dynamic.safety]*.
>
>
> Safely-derived pointers are only safe from a garbage collector. What=E2=
=80=99s=20
> important is that the addition operation be well-formed. In terms of=20
> [expr.add] =C2=A75.7/5, this means that the result pointer must reference=
 the=20
> same char array as the argument. I think =E2=80=9Cmemory block=E2=80=9D i=
s close enough;=20
> someone will fix it if the proposal is voted in.
>
> (By the way, the paper incorrectly cites =C2=A75.7/5 as 5.7.5.)
>

*[expr.add]* provides me an idea for an alternate wording, then:

The result is implementation-defined if the result is not undefined but one=
=20
or more among the following is true:

 * a > PTRDIFF_MAX       *<- it says ">=3D" in Matthew's draft, but=20
PTRDIFF_MAX can't be a power of 2, so =3D=3D would be undefined...*
 * p !=3D nullptr and does not point within the bounds of an object or arra=
y,=20
nor immediately past the end of an object or array.
 * The result of aligning p, if converted as if by reinterpret_cast<void *>=
(
*result*), would not compare equal to nullptr nor to reinterpret_cast<void=
=20
*>(q) for some q pointing within the bounds of some object or some array,=
=20
or immediately past the end of some object or some array.  [*Note:* "Some=
=20
object" or "some array" may be, and in typical programs usually will be,=20
the same as the one inside which p points.* --end note*]

If we want to allow implementations that actually throw an exception the=20
moment you even form a bad pointer, such as some Lua-based C++ interpreter=
=20
I've heard of, add something like the following:

 * The implementation follows a policy of *strict pointer safety*, p !=3D=
=20
nullptr, and aligning p results in an invalid pointer value.  (See=20
*[basic.stc.dynamic.safety]*.)

Melissa

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_6767_676575160.1409125434920
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, August 26, 2014 9:59:50 PM UTC-7, Thiago Macie=
ira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Tuesday 26 August=
 2014 21:25:43 Myriachan wrote:
<br>&gt; template &lt;class integral&gt;
<br>&gt; &nbsp; constexpr typename enable_if&lt;is_integral&lt;<wbr>integra=
l&gt;::value &amp;&amp; !is_same&lt;
<br>&gt; integral, bool&gt;::value, bool&gt;::type
<br>&gt; &nbsp; is_aligned(integral x, size_t a) noexcept {
<br>&gt; &nbsp; &nbsp; return (x &amp; (integral(a) - 1)) =3D=3D 0;
<br>&gt; &nbsp; }
<br>&gt;=20
<br>I don't think we need the first one. This was about pointer alignment.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" targ=
et=3D"_blank">kde.org</a>
<br></blockquote><div><br>That's fine if we want to get rid of all the=20
integer stuff in his proposal.&nbsp; I just meant it as a fix for some issu=
es
 that arise if we keep it.<br><br><br></div>On Tuesday, August 26, 2014 11:=
36:10 PM UTC-7, David Krauss wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div style=3D"word-wrap:break-word"><br><div><div>On 2014=E2=80=9308=
=E2=80=9327, at 12:25 PM, Myriachan &lt;<a target=3D"_blank">myri...@gmail.=
com</a>&gt; wrote:</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div=
>&nbsp;* The proper wording for the "memory block" stuff I believe is to re=
place the two lines with: "<span style=3D"font-family:courier new,monospace=
">p</span> is not a <i>safely-derived</i> pointer" and "The result, if conv=
erted as if by <span style=3D"font-family:courier new,monospace">reinterpre=
t_cast&lt;void *&gt;(</span><i>result</i><span style=3D"font-family:courier=
 new,monospace">)</span>, would not compare equal to <span style=3D"font-fa=
mily:courier new,monospace">reinterpret_cast&lt;void *&gt;(q)</span> for so=
me safely-derived pointer <span style=3D"font-family:courier new,monospace"=
>q</span> (ignoring <i>cv-</i>qualifiers)".&nbsp; My idea for this wording =
is from <b>[basic.stc.dynamic.safety]</b>.<br></div></div></blockquote><div=
><br></div></div>Safely-derived
 pointers are only safe from a garbage collector. What=E2=80=99s important =
is=20
that the addition operation be well-formed. In terms of [expr.add]=20
=C2=A75.7/5, this means that the result pointer must reference the same <fo=
nt face=3D"Courier">char</font> array as the argument. I think =E2=80=9Cmem=
ory block=E2=80=9D is close enough; someone will fix it if the proposal is =
voted in.<div><br></div><div>(By the way, the paper incorrectly cites =C2=
=A75.7/5 as 5.7.5.)</div></div></blockquote><div><br><b>[expr.add]</b> prov=
ides me an idea for an alternate wording, then:<br><br>The result is implem=
entation-defined if the result is not undefined but one or more among the f=
ollowing is true:<br><br>&nbsp;* <span style=3D"font-family: courier new,mo=
nospace;">a &gt; PTRDIFF_MAX</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>=
&lt;- it says "<span style=3D"font-family: courier new,monospace;">&gt;=3D<=
/span>" in Matthew's draft, but <span style=3D"font-family: courier new,mon=
ospace;">PTRDIFF_MAX</span> can't be a power of 2, so <span style=3D"font-f=
amily: courier new,monospace;">=3D=3D</span> would be undefined...</i><br>&=
nbsp;* <span style=3D"font-family: courier new,monospace;">p !=3D nullptr</=
span> and does not point within the bounds of an object or array, nor immed=
iately past the end of an object or array.<br>&nbsp;* The result of alignin=
g <span style=3D"font-family: courier new,monospace;">p</span>, if converte=
d as if by <span style=3D"font-family: courier new,monospace;">reinterpret_=
cast&lt;void *&gt;(</span><i>result</i><span style=3D"font-family: courier =
new,monospace;">)</span>, would not compare equal to <span style=3D"font-fa=
mily: courier new,monospace;">nullptr</span> nor to <span style=3D"font-fam=
ily: courier new,monospace;">reinterpret_cast&lt;void *&gt;(q)</span> for s=
ome <span style=3D"font-family: courier new,monospace;">q</span> pointing w=
ithin the bounds of some object or some array, or immediately past the end =
of some object or some array.&nbsp; [<i>Note:</i> "Some object" or "some ar=
ray" may be, and in typical programs usually will be, the same as the one i=
nside which <span style=3D"font-family: courier new,monospace;">p</span> po=
ints.<i> --end note</i>]<br><br>If we want to allow implementations that ac=
tually throw an exception the moment you even form a bad pointer, such as s=
ome Lua-based C++ interpreter I've heard of, add something like the followi=
ng:<br><br>&nbsp;* The implementation follows a policy of <i>strict pointer=
 safety</i>, <span style=3D"font-family: courier new,monospace;">p !=3D nul=
lptr</span>, and aligning <span style=3D"font-family: courier new,monospace=
;">p</span> results in an invalid pointer value.&nbsp; (See <b>[basic.stc.d=
ynamic.safety]</b>.)<br><br>Melissa<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_6767_676575160.1409125434920--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 27 Aug 2014 05:51:05 -0700 (PDT)
Raw View
------=_Part_4889_1650489800.1409143865733
Content-Type: text/plain; charset=UTF-8



On Wednesday, August 27, 2014 12:25:44 AM UTC-4, Myriachan wrote:
>
>
>
> I like this one I came up with:
>
>
That looks fine, except that we don't need a nullptr_t overload as
nullptr_t converts to const volatile void*.


On Wednesday, August 27, 2014 12:59:50 AM UTC-4, Thiago Macieira wrote:
>
>
> I don't think we need the first one. This was about pointer alignment.
>
>
I'd like to keep the integer alignment functions. They will need to exist
anyway under the covers for most implementations and exposing them is
useful for operating system kernel developers who treat pointers as
integers in their memory management systems.


On Wednesday, August 27, 2014 3:43:55 AM UTC-4, Myriachan wrote:
>
>
> *[expr.add]* provides me an idea for an alternate wording, then:
>
> The result is implementation-defined if the result is not undefined but
> one or more among the following is true:
>
>  * a > PTRDIFF_MAX       *<- it says ">=" in Matthew's draft, but
> PTRDIFF_MAX can't be a power of 2, so == would be undefined...*
>  * p != nullptr and does not point within the bounds of an object or
> array, nor immediately past the end of an object or array.
>  * The result of aligning p, if converted as if by reinterpret_cast<void
> *>(*result*), would not compare equal to nullptr nor to reinterpret_cast<void
> *>(q) for some q pointing within the bounds of some object or some array,
> or immediately past the end of some object or some array.  [*Note:* "Some
> object" or "some array" may be, and in typical programs usually will be,
> the same as the one inside which p points.* --end note*]
>

There's a slight difference in semantics here. You're saying the result is
IB if it does not point within any valid "memory block". Mine says that the
result IB if the result does not point to the same "memory block" as p. I
think we need to enforce that it points to the same block. If you do
pointer arithmetic to an array, go out of bounds, and just happen to land
in another object, the result is still UB.

>
> If we want to allow implementations that actually throw an exception the
> moment you even form a bad pointer, such as some Lua-based C++ interpreter
> I've heard of, add something like the following:
>
>  * The implementation follows a policy of *strict pointer safety*, p !=
> nullptr, and aligning p results in an invalid pointer value.  (See
> *[basic.stc.dynamic.safety]*.)
>

Wouldn't this conflict with the implementation defined behaviors we have
added? If you do an align_down() for a simd loop and land at a few bytes
before the array, would this trigger such an exception?

--

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

------=_Part_4889_1650489800.1409143865733
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, August 27, 2014 12:25:44 AM UTC-4, M=
yriachan wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); bo=
rder-left-style: solid; padding-left: 1ex;"><div dir=3D"ltr"><br><div><br>I=
 like this one I came up with:<br><br></div></div></blockquote><div><br></d=
iv><div>That looks fine, except that we don't need a nullptr_t overload as =
nullptr_t converts to const volatile void*.&nbsp;</div><br><br>On Wednesday=
, August 27, 2014 12:59:50 AM UTC-4, Thiago Macieira wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1p=
x; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding=
-left: 1ex;"><br>I don't think we need the first one. This was about pointe=
r alignment.&nbsp;<br><br></blockquote><div><br></div><div>I'd like to keep=
 the integer alignment functions. They will need to exist anyway under the =
covers for most implementations and exposing them is useful for operating s=
ystem kernel developers who treat pointers as integers in their memory mana=
gement systems.</div><div><br></div><div>&nbsp;</div>On Wednesday, August 2=
7, 2014 3:43:55 AM UTC-4, Myriachan wrote:<blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div><br><b>[expr.add]</b> provides me an idea=
 for an alternate wording, then:<br><br>The result is implementation-define=
d if the result is not undefined but one or more among the following is tru=
e:<br><br>&nbsp;* <span style=3D"font-family:courier new,monospace">a &gt; =
PTRDIFF_MAX</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>&lt;- it says "<s=
pan style=3D"font-family:courier new,monospace">&gt;=3D</span>" in Matthew'=
s draft, but <span style=3D"font-family:courier new,monospace">PTRDIFF_MAX<=
/span> can't be a power of 2, so <span style=3D"font-family:courier new,mon=
ospace">=3D=3D</span> would be undefined...</i><br>&nbsp;* <span style=3D"f=
ont-family:courier new,monospace">p !=3D nullptr</span> and does not point =
within the bounds of an object or array, nor immediately past the end of an=
 object or array.<br>&nbsp;* The result of aligning <span style=3D"font-fam=
ily:courier new,monospace">p</span>, if converted as if by <span style=3D"f=
ont-family:courier new,monospace">reinterpret_cast&lt;void *&gt;(</span><i>=
result</i><span style=3D"font-family:courier new,monospace">)</span>, would=
 not compare equal to <span style=3D"font-family:courier new,monospace">nul=
lptr</span> nor to <span style=3D"font-family:courier new,monospace">reinte=
rpret_cast&lt;void *&gt;(q)</span> for some <span style=3D"font-family:cour=
ier new,monospace">q</span> pointing within the bounds of some object or so=
me array, or immediately past the end of some object or some array.&nbsp; [=
<i>Note:</i> "Some object" or "some array" may be, and in typical programs =
usually will be, the same as the one inside which <span style=3D"font-famil=
y:courier new,monospace">p</span> points.<i> --end note</i>]<br></div></div=
></blockquote><div><br></div><div>There's a slight difference in semantics =
here. You're saying the result is IB if it does not point within any valid =
"memory block". Mine says that the result IB if the result does not point t=
o the same "memory block" as p. I think we need to enforce that it points t=
o the same block. If you do pointer arithmetic to an array, go out of bound=
s, and just happen to land in another object, the result is still UB.</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>If w=
e want to allow implementations that actually throw an exception the moment=
 you even form a bad pointer, such as some Lua-based C++ interpreter I've h=
eard of, add something like the following:<br><br>&nbsp;* The implementatio=
n follows a policy of <i>strict pointer safety</i>, <span style=3D"font-fam=
ily:courier new,monospace">p !=3D nullptr</span>, and aligning <span style=
=3D"font-family:courier new,monospace">p</span> results in an invalid point=
er value.&nbsp; (See <b>[basic.stc.dynamic.safety]</b>.)<br></div></div></b=
lockquote><div>&nbsp;</div><div>Wouldn't this conflict with the implementat=
ion defined behaviors we have added? If you do an align_down() for a simd l=
oop and land at a few bytes before the array, would this trigger such an ex=
ception?</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4889_1650489800.1409143865733--

.


Author: Myriachan <myriachan@gmail.com>
Date: Wed, 27 Aug 2014 13:53:07 -0700 (PDT)
Raw View
------=_Part_7547_1105501960.1409172787845
Content-Type: text/plain; charset=UTF-8

On Wednesday, August 27, 2014 5:51:05 AM UTC-7, Matthew Fioravante wrote:
>
>
>
On Wednesday, August 27, 2014 3:43:55 AM UTC-4, Myriachan wrote:
>>
>>
>> *[expr.add]* provides me an idea for an alternate wording, then:
>>
>> The result is implementation-defined if the result is not undefined but
>> one or more among the following is true:
>>
>>  * a > PTRDIFF_MAX       *<- it says ">=" in Matthew's draft, but
>> PTRDIFF_MAX can't be a power of 2, so == would be undefined...*
>>  * p != nullptr and does not point within the bounds of an object or
>> array, nor immediately past the end of an object or array.
>>  * The result of aligning p, if converted as if by reinterpret_cast<void
>> *>(*result*), would not compare equal to nullptr nor to reinterpret_cast<void
>> *>(q) for some q pointing within the bounds of some object or some
>> array, or immediately past the end of some object or some array.  [
>> *Note:* "Some object" or "some array" may be, and in typical programs
>> usually will be, the same as the one inside which p points.* --end note*]
>>
>
> There's a slight difference in semantics here. You're saying the result is
> IB if it does not point within any valid "memory block". Mine says that the
> result IB if the result does not point to the same "memory block" as p. I
> think we need to enforce that it points to the same block. If you do
> pointer arithmetic to an array, go out of bounds, and just happen to land
> in another object, the result is still UB.
>

Thiago wanted the ability to align a pointer to a page boundary, even if
that is outside all memory blocks, as implementation-defined behavior
instead of undefined behavior.  I agree with him that this can be useful
behavior.  Whether to include it is an interesting question; I certainly
think that an implementation could decide to make it undefined behavior.


>
>> If we want to allow implementations that actually throw an exception the
>> moment you even form a bad pointer, such as some Lua-based C++ interpreter
>> I've heard of, add something like the following:
>>
>>  * The implementation follows a policy of *strict pointer safety*, p !=
>> nullptr, and aligning p results in an invalid pointer value.  (See
>> *[basic.stc.dynamic.safety]*.)
>>
>
> Wouldn't this conflict with the implementation defined behaviors we have
> added? If you do an align_down() for a simd loop and land at a few bytes
> before the array, would this trigger such an exception?
>

Yes, it would if the implementation didn't allow pointers to "exit" memory
blocks like that.  That's why I have the first clause: that rule only
applies for implementations that use strict pointer safety.  Most
implementations do not have strict pointer safety.

Melissa

--

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

------=_Part_7547_1105501960.1409172787845
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 27, 2014 5:51:05 AM UTC-7, Matthew Fi=
oravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>&nbsp;</di=
v></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
">On Wednesday, August 27, 2014 3:43:55 AM UTC-4, Myriachan wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br><b>[expr.add]</b> =
provides me an idea for an alternate wording, then:<br><br>The result is im=
plementation-defined if the result is not undefined but one or more among t=
he following is true:<br><br>&nbsp;* <span style=3D"font-family:courier new=
,monospace">a &gt; PTRDIFF_MAX</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <=
i>&lt;- it says "<span style=3D"font-family:courier new,monospace">&gt;=3D<=
/span>" in Matthew's draft, but <span style=3D"font-family:courier new,mono=
space">PTRDIFF_MAX</span> can't be a power of 2, so <span style=3D"font-fam=
ily:courier new,monospace">=3D=3D</span> would be undefined...</i><br>&nbsp=
;* <span style=3D"font-family:courier new,monospace">p !=3D nullptr</span> =
and does not point within the bounds of an object or array, nor immediately=
 past the end of an object or array.<br>&nbsp;* The result of aligning <spa=
n style=3D"font-family:courier new,monospace">p</span>, if converted as if =
by <span style=3D"font-family:courier new,monospace">reinterpret_cast&lt;vo=
id *&gt;(</span><i>result</i><span style=3D"font-family:courier new,monospa=
ce">)</span>, would not compare equal to <span style=3D"font-family:courier=
 new,monospace">nullptr</span> nor to <span style=3D"font-family:courier ne=
w,monospace">reinterpret_cast&lt;void *&gt;(q)</span> for some <span style=
=3D"font-family:courier new,monospace">q</span> pointing within the bounds =
of some object or some array, or immediately past the end of some object or=
 some array.&nbsp; [<i>Note:</i> "Some object" or "some array" may be, and =
in typical programs usually will be, the same as the one inside which <span=
 style=3D"font-family:courier new,monospace">p</span> points.<i> --end note=
</i>]<br></div></div></blockquote><div><br></div><div>There's a slight diff=
erence in semantics here. You're saying the result is IB if it does not poi=
nt within any valid "memory block". Mine says that the result IB if the res=
ult does not point to the same "memory block" as p. I think we need to enfo=
rce that it points to the same block. If you do pointer arithmetic to an ar=
ray, go out of bounds, and just happen to land in another object, the resul=
t is still UB.</div></div></blockquote><div><br>Thiago wanted the ability t=
o align a pointer to a page boundary, even if that is outside all memory bl=
ocks, as implementation-defined behavior instead of undefined behavior.&nbs=
p; I agree with him that this can be useful behavior.&nbsp; Whether to incl=
ude it is an interesting question; I certainly think that an implementation=
 could decide to make it undefined behavior.<br>&nbsp;</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><br>If we want to allow implementations t=
hat actually throw an exception the moment you even form a bad pointer, suc=
h as some Lua-based C++ interpreter I've heard of, add something like the f=
ollowing:<br><br>&nbsp;* The implementation follows a policy of <i>strict p=
ointer safety</i>, <span style=3D"font-family:courier new,monospace">p !=3D=
 nullptr</span>, and aligning <span style=3D"font-family:courier new,monosp=
ace">p</span> results in an invalid pointer value.&nbsp; (See <b>[basic.stc=
..dynamic.safety]</b>.)<br></div></div></blockquote><div>&nbsp;</div><div>Wo=
uldn't this conflict with the implementation defined behaviors we have adde=
d? If you do an align_down() for a simd loop and land at a few bytes before=
 the array, would this trigger such an exception?</div></div></blockquote><=
div><br>Yes, it would if the implementation didn't allow pointers to "exit"=
 memory blocks like that.&nbsp; That's why I have the first clause: that ru=
le only applies for implementations that use strict pointer safety.&nbsp; M=
ost implementations do not have strict pointer safety.<br><br>Melissa<br></=
div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_7547_1105501960.1409172787845--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 27 Aug 2014 15:05:01 -0700
Raw View
On Wednesday 27 August 2014 13:53:07 Myriachan wrote:
> Thiago wanted the ability to align a pointer to a page boundary, even if
> that is outside all memory blocks, as implementation-defined behavior
> instead of undefined behavior.  I agree with him that this can be useful
> behavior.  Whether to include it is an interesting question; I certainly
> think that an implementation could decide to make it undefined behavior.

Here's an example:

void f()
{
 char buffer[256];
 fill_buffer(&buffer);

 char *p = std::align_down(buffer, 32); // size of an AVX register
 avx_operate(p, buffer);
}

If we say that align_down is UB if the result is outside of the memory block,
then the compiler can assume that it does *not* fall outside of the block. In
turn, an intrinsic-based implementation of align_down could return an
unexpected result, like &buffer[0] or the first 32-byte-aligned char inside the
buffer.

And why should a compiler implement align_down as an intrinsic? Why not, the
compiler knows where it placed variables in memory and what alignment it
requested from the assembler, so it might know the pointer is already aligned.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

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

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 27 Aug 2014 15:31:21 -0700 (PDT)
Raw View
------=_Part_5437_778294940.1409178681693
Content-Type: text/plain; charset=UTF-8



On Wednesday, August 27, 2014 6:05:07 PM UTC-4, Thiago Macieira wrote:
>
>
> void f()
> {
>         char buffer[256];
>         fill_buffer(&buffer);
>
>         char *p = std::align_down(buffer, 32);        // size of an AVX
> register
>         avx_operate(p, buffer);
> }
>
> If we say that align_down is UB if the result is outside of the memory
> block,
> then the compiler can assume that it does *not* fall outside of the block.
> In
> turn, an intrinsic-based implementation of align_down could return an
> unexpected result, like &buffer[0] or the first 32-byte-aligned char
> inside the
> buffer.
>
>
The current version of the paper should allow for this use case to be IB. I
also added a section to explain the reasoning and it has a simd example
much like the one you just posted.

--

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

------=_Part_5437_778294940.1409178681693
Content-Type: text/html; charset=UTF-8

<div dir="ltr"><br><br>On Wednesday, August 27, 2014 6:05:07 PM UTC-4, Thiago Macieira wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>void f()
<br>{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char buffer[256];
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fill_buffer(&amp;buffer);
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char *p = std::align_down(buffer, 32);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// size of an AVX register
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avx_operate(p, buffer);
<br>}
<br>
<br>If we say that align_down is UB if the result is outside of the memory block,
<br>then the compiler can assume that it does *not* fall outside of the block. In
<br>turn, an intrinsic-based implementation of align_down could return an
<br>unexpected result, like &amp;buffer[0] or the first 32-byte-aligned char inside the
<br>buffer.
<br>
<br></blockquote><div><br>The current version of the paper should allow for this use case to be IB. I also added a section to explain the reasoning and it has a simd example much like the one you just posted. <br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_5437_778294940.1409178681693--

.