日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

C/C++ strict-aliasing

發(fā)布時(shí)間:2024/9/5 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++ strict-aliasing 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近發(fā)現(xiàn)了一個(gè)奇怪的編譯參數(shù)-fno-strict-aliasing,好奇之下做了一點(diǎn)研究;

?

重點(diǎn)參考Understanding C/C++ Strict Aliasing;

所謂的aliasing就是多個(gè)變量指向同一塊內(nèi)存,變量之間互為別名;

strict-aliasing是一種編譯器希望開發(fā)者遵守的規(guī)則:雖然C/C++變量可以隨便賦值(強(qiáng)制類型轉(zhuǎn)換),但也請(qǐng)你們收斂一點(diǎn),別太天馬行空了;

如果開發(fā)者按照這個(gè)規(guī)則寫代碼了,編譯器就可以做更好的代碼優(yōu)化,比如這個(gè)例子:

void foo(double *dblptr) {anint = 1;*dblptr = 0;bar(anint); }

如果開發(fā)者能夠注意不要把int*轉(zhuǎn)成double*,bar(anint)可以直接優(yōu)化成bar(1);

但沒有任何約束不允許這樣做,因而編譯器不敢做這樣的優(yōu)化,只能在bar(anint)將anint傳入bar之前加一條匯編指令再讀一下anint的值;

如果開發(fā)者確定自己的代碼遵守這樣的規(guī)則了,可以在編譯時(shí)加一個(gè)優(yōu)化參數(shù)-fstrict-aliasing,這個(gè)參數(shù)在gcc的-O2、-O3、-Os優(yōu)化級(jí)別下都是默認(rèn)開啟的。

?

然后我對(duì)Understanding C/C++ Strict Aliasing文中的兩個(gè)主要例子做了一下測試:

例子一:

#include <stdio.h>int anint;void bar(int a) {printf("%d\n", a); }void foo(double *dblptr) {anint = 1;*dblptr = 0;bar(anint); }int main() {foo((double*)&anint);return 0; }
編譯器版本編譯參數(shù)結(jié)果
gcc 4.4.7g++0
?g++ -O31
?g++ -O3 -fno-strict-aliasing0
gcc 4.8.5g++0
?g++ -O31
?g++ -O3 -fno-strict-aliasing0
gcc 7.3.0g++0
?g++ -O31
?g++ -O3 -fno-strict-aliasing0

?可以看到,這個(gè)case被gcc編譯器優(yōu)化壞了,可以用-fno-strict-aliasing規(guī)避;

?

例子二:

#include <iostream> #include <iomanip>using namespace std;typedef unsigned int uint32_t; typedef unsigned short uint16_t;uint32_t swaphalves(uint32_t a) {uint32_t acopy = a;uint16_t *ptr = (uint16_t*)&acopy;// can't use static_cast<>, not legal.// you should be warned by that.uint16_t tmp = ptr[0];ptr[0] = ptr[1];ptr[1] = tmp;return acopy; }int main() {uint32_t a;a = 32;cout << hex << setfill('0') << setw(8) << a << endl;a = swaphalves(a);cout << setw(8) << a << endl; }
編譯器版本編譯參數(shù)結(jié)果
gcc 4.4.7g++00000020
00200000
?g++ -O300000020
00000020
gcc 4.8.5g++00000020
00200000
?g++ -O300000020
00200000
gcc 7.3.0g++00000020
00200000
?g++ -O300000020
00200000

發(fā)現(xiàn)這個(gè)case有點(diǎn)意思,只在4.4版本的編譯器上會(huì)出現(xiàn)問題,高版本編譯器上已經(jīng)修正了。

沒有精力再深入研究,就到此為止。

?

最后再貼上strict aliasing的規(guī)則說明,下面這篇文章給出了較好的中文翻譯,而且作者顯然比我研究的更深入,我就直接抄過來了:

https://blog.csdn.net/dbzhang800/article/details/6720141

  • 兼容類型(指相同類型?)或差別僅在于signed、unsigned、const、volatile的類型(比如 const unsigned long *和 long*)
  • 聚合類型(struct或class)或聯(lián)合類型(union)可以alias它們所包含的類型(比如 int 和 包含有int的結(jié)構(gòu)體(包括間接包含))
  • 字符類型(char *、signed char*、unsinged char*)可以 alias 任何類型的指針
  • [C++] 基類的類型(可能帶有const、volatile等cv修飾)可以alias派生類的類型

?

轉(zhuǎn)載于:https://www.cnblogs.com/ZisZ/p/9105383.html

總結(jié)

以上是生活随笔為你收集整理的C/C++ strict-aliasing的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。