Topic: memlaunder, an (incomplete) proposal to loosen


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Thu, 16 May 2013 14:42:14 -0500
Raw View
If C++ needs anything, it is less type punning, not more.
More principled and typed data access, not less.

--
Gabriel Dos Reis, http://www.axiomatics.org/~gdr/

--

---
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/?hl=en.



.


Author: amluto@gmail.com
Date: Thu, 23 May 2013 14:35:28 -0700 (PDT)
Raw View
------=_Part_866_6115967.1369344928739
Content-Type: text/plain; charset=ISO-8859-1

On Thursday, May 16, 2013 12:42:14 PM UTC-7, Gabriel Dos Reis wrote:
>
>
> If C++ needs anything, it is less type punning, not more.
> More principled and typed data access, not less.
>
>
I agree for most purposes.  But sometimes code wants to access and (ab)use
underlying representations of types [1] or do systems programming [2], and
having an explicit way to tell the compiler to please get out of the way
would be nice.

I actually think that C++ is too permissive in other respects.  For
example, I currently have an issue with a template<typename T> that
generates terrible code if T is size_t because then the compiler must
assume that a T* can alias all of the private size_t members of the class.

The former is a correctness problem, though, which makes me more inclined
to try to come up with ways to fix it.

[1] The in-progress cap'n'proto library, for example, seems excellent, but
I don't see how it could be written in a way that both avoids undefined
behavior due to type punning and generates good code on actual compiles.
(To be fair, the new relaxed union rules probably help.)

[2] Good luck writing something like Linux without something like this and
without relying on the compiler to not do certain legal optimizations.

--Andy



> --
> Gabriel Dos Reis, http://www.axiomatics.org/~gdr/
>

--

---
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/?hl=en.



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

On Thursday, May 16, 2013 12:42:14 PM UTC-7, Gabriel Dos Reis wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;">
<br>If C++ needs anything, it is less type punning, not more. &nbsp;
<br>More principled and typed data access, not less.
<br>
<br></blockquote><div><br>I agree for most purposes.&nbsp; But sometimes co=
de wants to access and (ab)use underlying representations of types [1] or d=
o systems programming [2], and having an explicit way to tell the compiler =
to please get out of the way would be nice.<br><br>I actually think that C+=
+ is too permissive in other respects.&nbsp; For example, I currently have =
an issue with a template&lt;typename T&gt; that generates terrible code if =
T is size_t because then the compiler must assume that a T* can alias all o=
f the private size_t members of the class.<br><br>The former is a correctne=
ss problem, though, which makes me more inclined to try to come up with way=
s to fix it.<br><br>[1] The in-progress cap'n'proto library, for example, s=
eems excellent, but I don't see how it could be written in a way that both =
avoids undefined behavior due to type punning and generates good code on ac=
tual compiles.&nbsp; (To be fair, the new relaxed union rules probably help=
..)<br><br>[2] Good luck writing something like Linux without something like=
 this and without relying on the compiler to not do certain legal optimizat=
ions.<br><br>--Andy<br><br>&nbsp;</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">--=20
<br>Gabriel Dos Reis, <a href=3D"http://www.axiomatics.org/~gdr/" target=3D=
"_blank">http://www.axiomatics.org/~<wbr>gdr/</a>
<br></blockquote>

<p></p>

-- <br />
&nbsp;<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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_866_6115967.1369344928739--

.


Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Thu, 23 May 2013 14:48:48 -0700
Raw View
On Thu, May 16, 2013 at 11:55 AM,  <amluto@gmail.com> wrote:
> There are a handful of decent reasons to want to engage in type-punning.
> The improved C99/C++11 union rules help a bit, but some cases aren't
> covered.  Here's an example:
>
> void WriteSomething(const void *data, size_t len)
> {
>   assert(len % 4 == 0);
>   auto d = reinterpret_cast<const uint32_t *d>(data);
>   for (int i = 0; i < len/4; i++)
>     Write4(d[i]);
> }

Rewrite this as:

void WriteSomething(const void *data, size_t len)
{
  assert(len % 4 == 0);
  for (int i = 0; i < len/4; i++) {
    uint32_t u32;
    memcpy(u32, &data[i*4], 4);
    Write4(u32);
  }
}

And then complain to your compiler vendor if that's less efficient.

> void ReadSomething(void *data, size_t len)
> {
>   assert(len % 4 == 0);
>   auto d = reinterpret_cast<uint32_t *d>(data);
>   for (int i = 0; i < len/4; i++)
>     d[i] = Read4();
> }
>
> This code is non-portable (it assumes 8-bit bytes, for one thing), but it
> ought to work.  This use case results in undefined behavior, though:
>
> void func()
> {
>   struct A { uint16_t x, y; };
>   A a{1,2};
>   WriteSomething(&a, sizeof(a));
>   ReadSomething(&a, sizeof(a));
>   std::cout << a.x << ' ' << a.y << std::endl;
> }
>
> The actual numbers passed to Write4 are implementation-depedent, but there's
> a worse problem: a.x and a.y have been accessed through a glvalue of type
> uint32_t, in violation of [basic.lval].10.
>
> This case is nasty -- the ReadSomething and WriteSomething functions don't
> know the types of the stored objects that they are accessing, so all they
> can safety do is to access them through char or unsigned char types, which
> is awkward at best.
>
> I propose a fix that should require only a small library change and (maybe)
> no or only minimal core language changes.  Define a new function memlaunder:
>
> void memlaunder(void *dest, const void *src, size_t len);
>
> If (dest != src), then memlaunder has no effect.  Otherwise memlaunder
> behaves as if it copies len bytes, starting at src, to temporary storage,
> and then copies the same bytes back to memory starting at dest.
>
> Now one could write:
>
> void ReadSomething(void *data, size_t len)
> {
>   assert(len % 4 == 0);
>   auto d = reinterpret_cast<uint32_t *d>(data);
>
>   /* The lifetime of the objects pointed to by data is now over -- the
> storage is being reused to store an array of type uint32_t -- see
> [basic.life].1-2. */
>
>   for (int i = 0; i < len/4; i++)
>     d[i] = Read4();
>
>   memlaunder(data, data, len);
>
>   /* The lifetime of the uint32_t objects ends after the first "copy" in
> memlaunder.  The lifetime of whatever type of objects data originally
> pointed to begins when the bytes are written. */
> }
>
> So long as (a) data points to trivially copyable objects and (b) whatever
> bytes get written are a valid representation, this should not invoke
> undefined behavior.
>
> WriteSomething needs something fancier, and I don't know how to do that
> without violating the rules that pointer that compare equal point to the
> same object and that const objects shouldn't be written to or have their
> lifetime end early.
>
>
> Any thoughts?  memlaunder should be straightforward to implement on existing
> compilers, since any uninlined function with that signature should already
> have that effect.
>
> --Andy
>
> --
>
> ---
> 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/?hl=en.
>
>

--

---
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/?hl=en.



.


Author: Gabriel Dos Reis <gdr@axiomatics.org>
Date: Fri, 24 May 2013 02:28:25 -0500
Raw View
amluto@gmail.com writes:

| On Thursday, May 16, 2013 12:42:14 PM UTC-7, Gabriel Dos Reis wrote:
|
|
|     If C++ needs anything, it is less type punning, not more.
|     More principled and typed data access, not less.
|
|
|
| I agree for most purposes.  But sometimes code wants to access and (ab)use
| underlying representations of types [1] or do systems programming [2], and

System programming necessary does not need reduced type guarantee and
increased type punning.

-- Gaby

--

---
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/?hl=en.



.