`

GCC warnings about strict-aliasing

阅读更多

warning: dereferencing type-punned pointer will break strict-aliasing rules

 

  在 gcc 2.x 下编译没有任何 warning 信息的代码换到 gcc 3.x 版本下之后出现了类似的 warning 。原因是 gcc 3 引入了 strict aliasing 架构,当编译时使用了 -fstrict-aliasing 参数(该参数在使用了 -O2 , -O3, -Os 优化参数的情况下默认生效),而源代码中存在一些违反了 strict-aliasing 规则的地方的话,编译器就会对这部分代码提出 warning 。

 

  gcc 3 manual 对于 -fstrict-aliasing 参数的说明是:Allows the compiler to assume the strictest aliasing rules applicable to the language being compiled.  For C (and C++), this activates optimizations based on the type of expressions.  In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same.  For example, an "unsigned int" can alias an "int", but not a "void*" or a "double".  A character type may alias any other type.

 

  简而言之, 在该参数激活的情况下,编译器希望不同类型的对象不会指向同一个地址。比如像这段代码:

int retLen;
someSetFunc((unsigned long *)&retLen);
printf ("ret len = %d\n" ,retLen);

 

  由于 someSetFunc 的传入参数类型定义为 unsigned long ,所以需要进行这样的指针类型强制 cast 。但对于 -fstrict-aliasing 优化参数来说,这样的转换是有潜在问题的(但实际上可能并不会造成任何问题)。所以如果现有的源代码存在太多这样的类型强制转换的问题的话,对这些代码进行修改也许会是场噩梦。最简单的方法是使用 -fno-strict-aliasing 参数来关闭 gcc 的优化选项,代价是放弃了 strict-aliasing 编译优化可能带来的可执行代码的性能提升。当然也可以用 -Wno-strict-aliasing 来屏蔽相关的 warning 信息,但无论这些 warning 信息多么的无关紧要,总还是“疑似危险”,所以可能的话最好还是把所有的 warning 都消灭掉。

 

  消灭的方法也不算复杂,正如 gcc manual 所示的那样,可以是采用 union 的不同成员变量来完成类型的转换。上面那段代码可以改为:

union u_retLen
{
int retLen;
unsigned long ptr;
};
someSetFunc(&u_retLen.ptr);
printf ("ret len = %d\n" ,u_retLen.retLen);

 

  虽然会使源代码变得丑陋,但对于大部分已有的源代码来说,这可能是改动最小的方案了。而对于新写的代码来说,如何更好的设计函数的入口参数(比如使用 void*)可能才是需要去思考的问题了。

 

原文链接: http://www.zeali.net/entry/454 MaDe1nZEAL

分享到:
评论

相关推荐

    严格别名规则“-fstrict-aliasing”和“-fno-strict-aliasing”及类型双关

    “-fstrict-aliasing”表示启用严格别名规则,“-fno-strict-aliasing”表示禁用严格别名规则,当gcc的编译优化参数为“-O2”、“-O3”和“-Os”时,默认会打开“-fstrict-aliasing”。 什么是严格别名规则?gcc对...

    warning: dereferencing type-punned pointer will break strict-aliasing rules

    "warning: dereferencing type-punned pointer will break strict-aliasing rules" 这个警告信息就与 GCC 编译器的 strict aliasing 规则有关,它是 GCC 从版本 3 开始引入的一个重要特性。 严格别名规则(strict ...

    gcc-4.8.0 gcc-4.9.0 gcc-5.1.0 gcc-6.1.0 gcc-7.1.0 gcc-8.1.0 gcc-9.1.0.7z

    gcc-4.8.0 gcc-4.9.0 gcc-5.1.0 gcc-6.1.0 gcc-7.1.0 gcc-8.1.0 gcc-9.1.0.7z 已验证可用,请放心下载。GCC used to stand for the GNU C Compiler, but since the compiler supports several other languages aside...

    gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-guneabi.tar.xz

    gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-guneabi.tar.xz gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-guneabi.tar.xz gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-guneabi.tar.xz gcc-linaro-4.9.4-2017.01-x86_...

    arm-linux-gcc和arm-elf-gcc 区别

    "arm-linux-gcc和arm-elf-gcc 的区别" arm-linux-gcc 和 arm-elf-gcc 是嵌入式交叉编译工具链中最常用的两个 GCC 工具链,它们之间的主要区别在于使用不同的 C 库文件。arm-linux-gcc 使用 GNU 的 Glibc,而 arm-...

    gcc-toolset-10-gcc-c++-10.2.1-8.2.el8.x86_64.rpm

    离线安装包,亲测可用

    gcc-c++-4.4.7-16.el6.x86_64.rpm

    warning: gcc-c++-4.4.7-3.el6.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY error: Failed dependencies: gcc = 4.4.7-3.el6 is needed by gcc-c++-4.4.7-3.el6.x86_64 libstdc++ = 4.4.7-...

    gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf

    gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译32-bit Armv7 Cortex-A, hard-float, little-endian目标中的裸机程序、u-boot、Linux kernel...

    gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz.7z

    gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf 是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译32-bit Armv7 Cortex-A, hard-float, little-endian目标中的裸机程序、u-boot、Linux kernel...

    gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz

    gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz 工具,我这个免费下载,鄙视那些要币的人!下载后先解压rar,解压就就是gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz了! 我本来想...

    gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.gz

    gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.tar是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译64-bit Armv8 Cortex-A, little-endian目标中的裸机程序、u-boot、Linux kernel、...

    gcc-arm-none-eabi-9-2020-q2-update.zip

    linux平台gcc编译器,gcc-arm-none-eabi-9-2020-q2-update-x64-linux.tar.bz2,gcc-arm-none-eabi-9-2020-q2-update-x64-linux.tar.bz2,只要5分,只要5分

    gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz.7z

    gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译64-bit Armv8 Cortex-A, little-endian hard-float, little-endian目标中的裸机程序、u-boot、...

    gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf

    gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf是由 Linaro 公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译32-bit Armv7 Cortex-A, hard-float, little-endian目标中的裸机程序、u-boot、Linux kernel...

    gcc-arm-none-eabi-10-2020-q4-major-win32.zip

    《Windows环境下ARM交叉工具链——GCC-ARM-NONE-EABI详解》 在嵌入式开发领域,ARM架构因其高效能和低功耗的特性而被广泛应用。为了在非ARM平台上编译针对ARM处理器的代码,我们需要一个交叉编译工具链。GCC-ARM-...

    gcc-arm-none-eabi-10.3-2021.07-win32.zip

    《GCC for ARM Cortex-M处理器:深入理解gcc-arm-none-eabi工具链》 GCC(GNU Compiler Collection)是一个开源的、跨平台的编译器套件,它支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada以及Go等。在...

    gcc-toolset-11-gcc-c++-11.1.1-6.el8.aarch64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    gcc-4.8.5-44.el7.x86_64相关包

    gcc-4.8.5-44.el7.x86_64.rpm gcc-c++-4.8.5-44.el7.x86_64.rpm gcc-gfortran-4.8.5-44.el7.x86_64.rpm libgfortran-4.8.5-44.el7.x86_64.rpm libquadmath-4.8.5-44.el7.x86_64.rpm libquadmath-devel-4.8.5-44.el7....

    gcc-arm-none-eabi-10-2020-q4-major.zip

    标题中的"gcc-arm-none-eabi-10-2020-q4-major.zip"是一个用于嵌入式开发的工具包,特别针对ARM架构的微控制器。这个工具集包含了用于编译、链接和其他相关任务的工具,是开源软件GCC(GNU Compiler Collection)的...

Global site tag (gtag.js) - Google Analytics