1
A
回答
1
可移植的方式是使用位移和掩碼到適當大小的字符串中。注意我說的是字符串,因爲這實際上是唯一需要關注字節順序的時候 - 在系統之間傳輸字節。
如果你想避免不必要的轉換(例如在小端架構上轉換成小端),那麼編譯時就沒有完全可移植的方法。但是您可以在運行時檢查以動態選擇一組轉換函數。
這確實有代碼不能內聯的缺點。以便攜方式編寫轉換並使用模板或內聯可能會更有效。結合半可移植的編譯時檢查,這與你會得到的一樣好。
更多閱讀:Detecting Endianness在編譯時。
+0
該鏈接中的解決方案實際上不工作/不便攜。事實證明,將整數轉換爲constexpr上下文中的字節序列是非法的,無論是通過顯式轉換還是聯合。 –
1
這是一個很好的問題。它促使我看看是否有任何方法可以在編譯時使用constexpr表達式來確定字節序。
事實證明,如果沒有預處理技巧,這是不可能的,因爲在constexpr上下文中評估時,無法將整數轉換爲字節序列(通過強制轉換或聯合)。
然而事實證明,在海灣合作委員會,與-O2編譯一個簡單的運行時檢查被優化掉,所以這實際上是最爲有效的:
#include <cstdint>
#include <iostream>
constexpr bool is_little_endian()
{
union endian_tester {
std::uint16_t n;
std::uint8_t p[4];
};
constexpr endian_tester sample = {0x0102};
return sample.p[0] == 0x2;
}
template<class Int>
Int to_little_endian(Int in)
{
if (is_little_endian()) {
return in;
}
else {
Int out = 0;
std::uint8_t* p = reinterpret_cast<std::uint8_t*>(std::addressof(out));
for (std::size_t byte = 0 ; byte < sizeof(in) ; ++byte)
{
auto part = (in >> (byte * 8)) & 0xff;
*p++ = std::uint8_t(part);
}
return out;
}
}
int main()
{
auto x = to_little_endian(10);
std::cout << x << std::endl;
}
這裏編譯就當是彙編輸出。一個英特爾(小端)平臺:
main:
subq $8, %rsp
#
# here is the call to to_little_endian()
#
movl $10, %esi
#
# that was it - it's been completely optimised away
#
movl std::cout, %edi
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
xorl %eax, %eax
addq $8, %rsp
ret
相關問題
- 1. 便攜式如何將-1轉換爲無符號類型?
- 2. 將便攜式msysGit轉換爲完全等效(但仍然便攜)
- 3. 以數學方式將簽名轉換爲無符號整數
- 4. 將float轉換爲bigint(又名便攜式獲取二進制指數和尾數)
- 5. 便攜式方式
- 6. 如何根據小數的值將小數整數轉換爲整數?
- 7. 如何以便攜方式與數據庫交談?
- 8. 如何在JAVA中將整數轉換爲24小時格式?
- 9. 轉換爲少數位的小尾數
- 10. 矢量調整大小 - 便攜式檢測方式
- 11. 小尾數爲整數
- 12. 將Windows Phone 8.1項目轉換爲便攜式庫
- 13. 非便攜式指針轉換警告
- 14. Python將整數轉換爲小時
- 15. 如何在Swift中將小數部分轉換爲整數
- 16. 如何將整數轉換爲PROLOG中的小數點?
- 17. 更簡潔的方法將整數除法轉換爲小數
- 18. 將12小時時間格式轉換爲24小時整數?
- 19. 便攜式C#數據庫
- 20. 使數據庫便攜式
- 21. 將所有整數列表轉換爲浮點數以便輸出的函數
- 22. 將32位無符號小尾數轉換爲javascript中的整數
- 23. 將以下函數轉換爲其尾遞歸形式
- 24. 如何將system.data.dataRow值轉換爲整數
- 25. 如何將postgres json轉換爲整數
- 26. 如何將整數轉換爲字符
- 27. 如何將日期轉換爲整數?
- 28. 如何將整數轉換爲日期?
- 29. 如何將整數轉換爲qbitarray?
- 30. 如何將Java.Lang.Enum轉換爲整數?
你想達到什麼目的?除非你做了一些時髦的轉換和取消指向各種大小整數的指針,否則你不需要擔心endianess。另請參閱[「htonl()vs __builtin_bswap32()」](http://stackoverflow.com/questions/21527957/htonl-vs-builtin-bswap32)上的這個問題,它討論了字節交換數字的替代方法。 – Jens
如果你不得不擺弄end,,你已經踏上了「不便攜」的境界。因此,以這樣一種方式來隔離它,其餘代碼可以使用適當的抽象,並且針對特定平臺實現*** ***平臺特定的實現。 –