Информация об изменениях

Сообщение Re[2]: Это UB ? от 02.07.2024 12:29

Изменено 02.07.2024 12:35 rg45

Re[2]: Это UB ?
Здравствуйте, ajanov, Вы писали:

A>
A>void foo(uint32_t x, std::uint8_t out[4])
A>{
A>    out[0] = x & 0x000000FF;
A>    out[1] = (x & 0x0000FF00) >> 8;
A>    out[2] = (x & 0x00FF0000) >> 16;
A>    out[3] = (x & 0xFF000000) >> 24;
A>}
A>


Немного оффтопа мимоходом. Очень опасная функция из серии "не верь глазам своим". Компилятор автоматически преобразовал объявление этой функции в void foo(uint32_t x, std::uint8_t* out) и, скорее всего, даже никаких предупреждений не выдал. Так что out здесь никакой не массив, а обычный указатель. А раз так, то в эту функцию можно передать массив ЛЮБОГО размера в качестве фактического параметра:

http://coliru.stacked-crooked.com/a/acf5ae2a080a66ef

#include <concepts>
#include <cstdint>

void foo(uint32_t x, uint8_t out[4])
{
    static_assert(std::same_as<uint8_t*, decltype(out)>);

    // . . .    
}

int main()
{
    uint8_t out[1]{};

    foo(42, out); // Oops! Заезд по памяти.
}


Так что, если и делать массивы параметрами функций, то обязательно через ссылки.
Re[2]: Это UB ?
Здравствуйте, ajanov, Вы писали:

A>
A>void foo(uint32_t x, std::uint8_t out[4])
A>{
A>    out[0] = x & 0x000000FF;
A>    out[1] = (x & 0x0000FF00) >> 8;
A>    out[2] = (x & 0x00FF0000) >> 16;
A>    out[3] = (x & 0xFF000000) >> 24;
A>}
A>


Немного оффтопа мимоходом. Очень опасная функция из серии "не верь глазам своим". Компилятор автоматически преобразовал объявление этой функции в void foo(uint32_t x, std::uint8_t* out) и, скорее всего, даже никаких предупреждений не выдал. Так что out здесь никакой не массив, а обычный указатель. А раз так, то в эту функцию можно передать массив ЛЮБОГО размера в качестве фактического параметра:

http://coliru.stacked-crooked.com/a/acf5ae2a080a66ef

#include <concepts>
#include <cstdint>

void foo(uint32_t x, uint8_t out[4])
{
    static_assert(std::same_as<uint8_t*, decltype(out)>);

    // . . .    
}

int main()
{
    uint8_t out[1]{};

    foo(42, out); // Oops! Заезд по памяти.
}


Так что, если и делать массивы параметрами функций, то обязательно через ссылки.

void foo(uint32_t x, uint8_t (?out)[4]);