最近遇到的一個C++的一個UB行為
前言
WPS在官方平臺是有ARM64的二進位制包的。
前段時間,我這收到社群使用者一個反饋,說WPS在樹莓派上遇到一個表格樣張開啟排版錯亂的問題。具體表現就是WPS在樹莓派上表現一個表格的樣張有問題。 表格是有左邊距屬性的,這個樣張在樹莓派上的表現是沒有左邊距,然後呢,在X64跟MIPS64上也不復現。
這就尷尬了,遇到這種問題,基本都是C++的UB的問題了。先在這裡盲猜一波。
定位程式碼
這種C++的跨平臺問題,實際上是很常見的。因為我們的程式碼也是Windows平臺遷移過來的嘛。基本上這類問題也是日更了。
最典型的問題,那就是long的位數了。
這個檔案的字尾是doc,我以為是二進位制格式的,打了個斷點跟了半天程式碼發現沒有跟進去,再詳細跟的時候發現是html格式的,不知道誰字尾給我改成了DOC。
我特麼。。。
這也是我日常修bug經常遇到各種奇怪的樣張的情況之一了。
程式碼
直接上錯誤程式碼吧,我把程式碼精簡了。
double
dTest
=
-
100。5
;
uint
uTest
=
dTest
;
std
::
cout
<<
uTest
<<
std
::
endl
;
輸出
4294967295
很好理解,符號位變了嘛。正常情況下。編譯器會給個警告的。會提示這裡有個轉化。
下面是msvc2019的警告
warning C4244: “初始化”: 從“double”轉換到“unsigned int”,可能丟失資料
雖說是警告,然後發現這個數也能夠正常的轉化出來。
在Linux下clang11跟gcc10上,這個都沒問題,跟windows表現一致,都是輸出這個數。 甚至於在MIPS上以及龍芯5000(LoongArch)上,這個數表現依舊是正常的。
但是在Arm64上。這個
uTest
上就變成了0。所以具體表現就是wps的某個樣張的表格的左邊距就變為0了。
只是沒想到這也能UB。
然後我查到了資料
附上相關的連結。
https://
stackoverflow。com/quest
ions/10541200/is-the-behaviour-of-casting-a-negative-double-to-unsigned-int-defined-in-the-c-s
搞CPP太難了。沒想到一個強轉也能UB。
問我為啥一開始這樣寫。
看了下git記錄是8年前的。
Windows沒問題,當然就一直這樣了。逃)