Date: Wed, 24 Jul 2013 19:05:25 -0500
On 24 July 2013 09:20, Nevin Liber <nevin_at_[hidden]> wrote:
> On 24 July 2013 06:58, Gabriel Dos Reis <gdr_at_[hidden]> wrote:
>
>> The "union hack" is treacherous and needs far more investigation
>> than it appears.
>
>
> So treacherous that people have been managing to use it for the last 30
> years or so?
>
>
>> Are we going to mandate that the reintepretation of
>> the bits cannot possibly yield trap representation?
>
>
> I wouldn't. This is for non-portable machine-specific code. If you blow
> a trap representation or an alignment access, you are on your own.
>
> If I wanted to do this via copying, I'd just use Java.
>
Assuming no alignment, packing, endian or malformed packet issues, here is
an example of what people want to do:
enum class Protocol : char
{
UDP = 17,
// ...
};
struct IPHeader
{
//...
Protocol protocol;
// ...
};
struct UDPHeader : IPHeader
{
//...
uint16_t length;
//...
char data[1];
};
union Header
{
IPHeader ip;
UDPHeader udp;
//...
};
// Deliver payload to f without copying
Payload(dynarray<char> const& packet, std::function<void(char const*, char
const*)> const& f)
{
// Want to overlay Header on packet.data()
auto& header = *static_cast<Header const*>(static_cast<void
const*>(packet.data()));
switch (header.ip.protocol)
{
case Protocol::UDP:
f(&header.udp.data[0], &header.udp.data[header.udp.length - 8]);
break;
//...
}
}
Q1: How many places has undefined behavior been invoked in the above?
Q2: What is the correct way to write this code?
> On 24 July 2013 06:58, Gabriel Dos Reis <gdr_at_[hidden]> wrote:
>
>> The "union hack" is treacherous and needs far more investigation
>> than it appears.
>
>
> So treacherous that people have been managing to use it for the last 30
> years or so?
>
>
>> Are we going to mandate that the reintepretation of
>> the bits cannot possibly yield trap representation?
>
>
> I wouldn't. This is for non-portable machine-specific code. If you blow
> a trap representation or an alignment access, you are on your own.
>
> If I wanted to do this via copying, I'd just use Java.
>
Assuming no alignment, packing, endian or malformed packet issues, here is
an example of what people want to do:
enum class Protocol : char
{
UDP = 17,
// ...
};
struct IPHeader
{
//...
Protocol protocol;
// ...
};
struct UDPHeader : IPHeader
{
//...
uint16_t length;
//...
char data[1];
};
union Header
{
IPHeader ip;
UDPHeader udp;
//...
};
// Deliver payload to f without copying
Payload(dynarray<char> const& packet, std::function<void(char const*, char
const*)> const& f)
{
// Want to overlay Header on packet.data()
auto& header = *static_cast<Header const*>(static_cast<void
const*>(packet.data()));
switch (header.ip.protocol)
{
case Protocol::UDP:
f(&header.udp.data[0], &header.udp.data[header.udp.length - 8]);
break;
//...
}
}
Q1: How many places has undefined behavior been invoked in the above?
Q2: What is the correct way to write this code?
-- Nevin ":-)" Liber <mailto:nevin_at_[hidden]> (847) 691-1404
Received on 2013-07-25 02:06:07