Skip to content

Instantly share code, notes, and snippets.

@AkiyukiOkayasu
Last active January 21, 2021 17:18
Show Gist options
  • Save AkiyukiOkayasu/3b34513d60015e274cd02e1d7b39e879 to your computer and use it in GitHub Desktop.
Save AkiyukiOkayasu/3b34513d60015e274cd02e1d7b39e879 to your computer and use it in GitHub Desktop.
バイト列生成、バイト列を別の型として解釈させる簡単なメモ書き
#include <iostream>
#include <cstdint>
#include <cstddef>
#include <array>
//std::array<std::byte, N>を生成する
//std::array<std::byte, 2> b = {0x00, 0xFF}; はintからstd::byteへの暗黙キャストでエラーになる
//std::array<std::byte, 2> b = {std::byte{0x00}, std::byte{0xFF}}; はエラーにならないが、面倒なのでmake_bytes(0x00, 0xFF) で生成できるようにした
template<typename... Ts>
constexpr std::array<std::byte, sizeof...(Ts)> make_bytes(Ts&&... args) noexcept {
return{std::byte(std::forward<Ts>(args))...};
}
// std::byte配列をint32_t配列としてType punningするサンプル
// https://wandbox.org/permlink/bQI745EyCajmo1DL
int main()
{
auto arr = make_bytes(0x08, 0x00, 0x00, 0x00,//8
0xFF, 0x00, 0x00, 0x00,//255
0xFF, 0xFF, 0xFF, 0xFF,//-1
0x78, 0xEC, 0xFF, 0xFF //-500
);
/*
* バイト配列をreinterpret_castでint32_tと再解釈する
* バイト配列はstd::byte以外にも文字型であればStrict Aliasing Rulesに違反しない
* unsigned char arr[] = {0x08, 0x00, 0x00, 0x00,//8
* 0xFF, 0x00, 0x00, 0x00,//255
* 0xFF, 0xFF, 0xFF, 0xFF,//-1
* 0x78, 0xEC, 0xFF, 0xFF //-5000
* };
* uint8_tはunsigned charのtypedefとして定義されていればStrict Aliasing Rulesに違反しないが、そうである保証はなく実装依存。
*/
auto r = reinterpret_cast<int32_t*>(arr.data());
std::cout << r[0] << ", " << r[1] << ", " << r[2] << ", " << r[3] << std::endl;// print: 8, 255, -1, -5000(アライメント要件を満たしていないのに正しい値がでてきた)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment