Cyberman.Wu 发表于 2012-09-03 12:40

关于GCC的strict aliasing

int sock_if_set_ip_addr(int sock, char *ifname, unsigned char ip)
{
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    struct sockaddr_in *_addr = (struct sockaddr_in *)&ifr.ifr_addr;
    _addr->sin_family = AF_INET;
    memcpy(&_addr->sin_addr.s_addr, ip, 4);
    if (ioctl(sock, SIOCSIFADDR, (void *)&ifr) < 0)
    {
      perror("ioctl(SIOCSIFADDR)");
      return -1;
    }

    return 0;
}
红色的地方会产生一个编译告警:warning: dereferencing pointer ‘_addr’ does break strict-aliasing rules改为用如下代码是可以避免这个Warning的:    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    memcpy(&addr.sin_addr.s_addr, ip, 4);
    memcpy(&ifr.ifr_addr, &addr, sizeof(addr));
但这样一来,多了一次无用的拷贝。

在Makefile中关闭这个Warning风险太大,而关闭strict aliasing有些资料上说会使编译器的优化变差一些。
这里有没有某种写法可以既避免无用的操作又避免产生这个Warning,或者有没有仅在某处关闭某个Warning、
之后就打开它的方法(类似于pc-lint的单行屏蔽,把风险降到最低)。

EricFisher 发表于 2012-09-04 10:55

感觉这个warning是第6行

struct sockaddr_in *_addr = (struct sockaddr_in *)&ifr.ifr_addr;

强制类型转换造成的。

看了下手册http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options中关于-fstrict-aliasing的介绍,如果关掉这个优化,自然就没有警告,但可能会失去一些优化机会。我不确定,在打开这个选项的情况下,如果有上述的警告,会不会造成优化出错,生成错误的程序代码。如果是这样的话,我觉得还是改改代码为好。

Cyberman.Wu 发表于 2012-09-10 11:51

回复 2# EricFisher


    这个地方代码应该是没问题的,不过整体关闭这个优化或者关闭这个warning都不太合适,所以才想知道能否“临时”禁止这个warning,
好像VC是有这种功能的。

EricFisher 发表于 2012-09-13 14:35

临时是指的只针对该文件么?如果是的话,修改makefile,对该文件使用-fno-strict-aliasing关掉该优化,或者-Wstrict-aliasing=n(n取1,2,3)关掉该警告。
页: [1]
查看完整版本: 关于GCC的strict aliasing