2015-06-14 21 views
0

是以下未定義行爲?使用_mm_loadu_si128會發生什麼,如果該參數指向一個字符串小於16個字節(

char s[] = "hello"; 
__m128i v = _mm_loadu_si128(reinterpret_cast < __mm_128i * >(s)); 

下面肯定是不確定的行爲,至少使用-fsanitize=address編譯時,抱怨閱讀過去緩衝區的結束。但SSE相當於正悄然接受。我認爲這是因爲在翻譯單元上證所內部函數不與-fsanitize=address

char s[] = "hello"; 
typedef __uint128_t T; 
T mask = ~(T(0)) >> (8 * (sizeof(T) - strlen(s))); 
T v = mask & *((T *)(s)); 
+0

C和C++中不同的語言。不要將C標籤用於C++問題! – Olaf

+2

因爲嘗試讀取內存頁末尾附近的內容並且未映射下一個內存頁而導致出現分頁錯誤,所以程序崩潰的可能性不大。它會發生。這是錯誤的代碼,簡單明瞭。 –

回答

0

一旦編譯爲你使用reinterpret_cast日e編譯器會丟失原始類型信息,並且您自己。請理解我,這種情況在這種情況下是不可避免的。我只想強調,在SSE運營的情況下,您有責任提供足夠的數據。

0

由於該標準沒有涉及編譯器特定的擴展,因此無法爲此指定UB。

你很可能會遇到對齊問題,並且陣列太短,加載的數據比分配的數據多(確實實際上表現出UB)。爲了確保,至少指定大小明確(但缺少NUL如果字符串太短的提防

所以:使用alignas(__mm_128i)以保函正確對齊,並宣佈uint8_t s[sizeof(__mm_128i)];

使用uint8_t保證8個字段,char實際上做

另一種可能是使用一個聯合,所以你並不需要一個reinterpret_cast這避免了兩個問題:。對齊和大小

相關問題