[ovs-dev] [PATCH] netdev: Fix strict-aliasing error in GCC 4.4

Ben Pfaff blp at nicira.com
Tue Dec 15 05:16:43 UTC 2009


Justin Pettit <jpettit at nicira.com> writes:

> The latest version of GCC flags a common socket convention as breaking
> strict-aliasing rules.  This commit removes the aliasing and gets rid of
> the scary warning.

To the best of my knowledge "union"s have very few extra
dispensations in the C standard versus other types regarding
aliasing.  I can only think of one and this case doesn't qualify
for that one.  So I think that it suppresses the warning but
doesn't actually fix the problem, standards-wise, that it is
warning about.

My favorite allowed form of aliasing (ha! I am geek!) is that
character types are allowed to alias anything.  The memcpy
function is required to copy data byte-by-byte ("as if" it was
byte-by-byte, anyhow), so that means that you can use memcpy() to
copy something into a region that has the "wrong type".

So this is what I would do (compile-tested only):

--8<---------------------------cut here--------------------------->8--

>From e61d3dc2acf9810c1a7cbd7332a39e35980d5d5e Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp at nicira.com>
Date: Mon, 14 Dec 2009 21:00:29 -0800
Subject: [PATCH] netdev-linux: Fix aliasing error.

The latest version of GCC flags a common socket convention as breaking
strict-aliasing rules.  This commit removes the aliasing and gets rid of
the scary warning.
---
 lib/netdev-linux.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 0dff508..18d3274 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1710,14 +1710,14 @@ netdev_linux_arp_lookup(const struct netdev *netdev,
                         uint32_t ip, uint8_t mac[ETH_ADDR_LEN])
 {
     struct arpreq r;
-    struct sockaddr_in *pa;
+    struct sockaddr_in sin;
     int retval;
 
     memset(&r, 0, sizeof r);
-    pa = (struct sockaddr_in *) &r.arp_pa;
-    pa->sin_family = AF_INET;
-    pa->sin_addr.s_addr = ip;
-    pa->sin_port = 0;
+    sin.sin_family = AF_INET;
+    sin.sin_addr.s_addr = ip;
+    sin.sin_port = 0;
+    memcpy(&r.arp_pa, &sin, sizeof sin);
     r.arp_ha.sa_family = ARPHRD_ETHER;
     r.arp_flags = 0;
     strncpy(r.arp_dev, netdev->name, sizeof r.arp_dev);
-- 
1.6.5





More information about the dev mailing list