LINUX.ORG.RU

Зависит от того, где ты это встретил, и насколько выровнено cnt. И да, почему так нельзя в С++?

Я так понимаю, в буфере хранятся адреса в чистом виде.

UVV ★★★★★ ()

Отчего наркомания? Обычное дело. И в С++ так можно, никто не запрещает.

Да, первый комментатор правильно подметил, что &buf[cnt] должен быть выровнен. На x86 не проблема, потому что там можно, а где-нибудь всё-таки упадёт.

a1batross ★★★★★ ()
Ответ на: комментарий от UVV

Я так понимаю, в буфере хранятся адреса в чистом виде.

Увы, вы не знаете указатели. Ясно же написано, что хотим по смещению из памяти получить значения с ручной конверсией типов.

vodz ★★★★★ ()
Ответ на: комментарий от UVV

И да, почему так нельзя в С++?

Ну попробуй сделать static_cast из char* в int*. Сразу ударит по рукам

Я так понимаю, в буфере хранятся адреса в чистом виде.

Нет, числа. Предполагается, что по адресу 4 байтное число и через кастование оно и читается

tyro33 ()

У тебя есть кусок данных, ты берешь из него 4х байтное число. Это не только не УБ, но вообще обычное дело в сях - встречается сплошь и рядом. Вот представь, тебе надо прочитать бинарные данные из файла в некую структуру, а read/fread вообще не в курсе ни о каких типах.

anonymous ()

Этот говнокод будет трапать на невыровненном доступе и надо использовать поразрядные сложения со сдигами в соответствии с endian хранения.

d_a ★★★★★ ()
Ответ на: комментарий от anonymous

Ну ок. Говорю же, не уверен был. Я в подобном коде выравнивал буфер по PAGE_SIZE, а в user space уже производил побайтовую конверсию (по типу как в ntoh, hton), а не как ТС хочет. Поэтому с подобными проблемами не сталкивался.

UVV ★★★★★ ()

Си - это кроссплатформенный ассемблер. Всё дозволено. Вся ответственность перекладывается на кодера. Если вопрос в том, можно ли так делать, то ответ однозначен - можно.

anonymous ()
Ответ на: комментарий от anonymous

Причем можно делать вещи и похуже. Вдруг у автора кода задача - вызвать падение. Или заложить бекдор. Или это часть эксплоита. Или его это просто прикалывает.

anonymous ()
Ответ на: комментарий от tyro33

6.5 Expressions:

7 An object shall have its stored value accessed only by an lvalue expression that has one of
the following types: 88)
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the
object,
— a type that is the signed or unsigned type corresponding to a qualified version of the
effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its
members (including, recursively, a member of a subaggregate or contained union), or
— a character type.

Да, это UB. Можно использовать memcpy().

xaizek ★★★★★ ()
Последнее исправление: xaizek (всего исправлений: 1)

Если ТОЛЬКО такой код, то можно. Но нужно следить чтобы потом не выползла конструкция вида

float size_pic2 = *((float*)&buf[cnt]);

т.к. обращения size_pic и size_pic2 будут считаться независимыми по правилам strict-aliasing. И могут быть перемешаны.

alexanius ()
Ответ на: комментарий от utf8nowhere

обращения size_pic и size_pic2 будут считаться независимыми по правилам strict-aliasing.

Они будут считаться независимыми, т.к. это разные объекты.

Указатель будет вести на один и тот же участок памяти, так что фактически это будет один объект.

alexanius ()
Ответ на: комментарий от xaizek

Давно интересует вопрос: а какое место в стандарте гарантирует, что после копирования байтов в объект с использованием memcpy этот объект будет содержать значение, являющееся интерпретацией этих байтов как представления соответствующего типа?

utf8nowhere ★★ ()
Ответ на: комментарий от utf8nowhere

Это чтобы вот так делать?

#include <iostream>

struct A {
  char a, b;
  void print() const {
    std::cout << "a = " << a << ", b = " << b << std::endl;
  }
};

int main() {
  reinterpret_cast<const A *>("12345")->print();
}

a = 1, b = 2
anonymous ()