Учитывая следующий код
#include <cassert>
#include <climits>
#include <cstdint>
#include <iostream>
static_assert(CHAR_BIT == 8, "A byte does not consist of 8 bits");
void func1(const int32_t& i)
{
const unsigned char* j = reinterpret_cast<const unsigned char*>(&i);
for(int k = 0; k < 4; ++k)
std::cout << static_cast<int>(j[k]) << ' ';
std::cout << '\n';
}
void func2(const int32_t& i)
{
const unsigned char (&j)[4] = reinterpret_cast<const unsigned char (&)[4]>(i);
for(int k = 0; k < 4; ++k)
std::cout << static_cast<int>(j[k]) << ' ';
std::cout << '\n';
}
int main() {
func1(-1);
func2(-1);
}
Из правил языка ясно, что func1
хорошо, так как указатели на unsigned char
могут иметь псевдоним любого другого типа. Мой вопрос: распространяется ли это на C ++ ссылки на C-массивы с известной длиной? Интуитивно я бы сказал, да. func2
четко определено или это вызывает неопределенное поведение?
Я пытался скомпилировать приведенный выше код с использованием Clang и GCC с каждой возможной комбинацией -Wextra -Wall -Wpedantic
и UBSAN, и не получал предупреждений и всегдатот же вывод. Очевидно, это не означает, что UB отсутствует, но я не смог вызвать ни одной из обычных ошибок оптимизации типа строго псевдонимов.