LINUX.ORG.RU

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

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

UVV ★★★★★
()

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

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

a1batross ★★★★★
()

Ты встретил это в чужом коде и спрашиваешь, нельзя ли так.

Bfgeshka ★★★★★
()

ЕМНИП так можно только с char*

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

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

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

vodz ★★★★★
()

В Си так тоже нельзя, но во многих компиляторах uint8_t — это alias для char, поэтому будет работать.

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

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

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

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

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

tyro33
() автор топика

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

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

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

Ну пусть читается. Big / little endian?

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

Я & посмотрел. Да, значит числа просто берёт

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

Вот надо, чтобы не падало. Потому и спрашиваю. В крестах компилятор сразу по рукам бьет за такое, как бы намекая,что может быть больно

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

Увы, вы не знаете указатели

Вывод охуителен и давит своим авторитетом

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

Ну вот ты выше про выравнивание писал, а я понятия не имею есть ли оно. То есть не всегда такая конструкция корректно сработает?

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

static_cast

Накурятся своих С++-style кастов, а потом у них то нельзя, это нельзя.

a1batross ★★★★★
()

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

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

надо, чтобы не падало

Вполне можно заменить на memcpy.

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

Да пока ничего не упало, просто у меня сомнения. Это embedded. Тут если упадет будет печалька

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

тогда при чем тут static_cast? в этом случан только реинтерпрет/си-стайл сработает. или тебе нужен философ-тред на 100500 страниц?

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

Ну это преобразование у тебя в цикле, судя по всему? Вот и следи, чтобы шаг цикла был cnt += sizeof(uint32_t)

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

Меня спросили почему в крестах так нельзя - я ответил. «Нельзя» в смысле может выйти совсем не то, что надо

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

Лорчую анонима. Если это kernel space, то только С-каст, если user space, то C++ way и reinterpret_cast

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

с такого рода операциями все гарантии дает программист

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

так 256 же, не? Если ты про сам buf, то там вроде бы пох должно быть, если у ТСа не DMA какой-нибудь. Поправьте, если не прав.

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

Тем не менее, в крестах прямой каст из char* в int* недопустим в соответствии со strict aliasing rule. Я не знаю есть ли такое в сишке, вот и спросил

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

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

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

Не совсем верно. Компилятор может сам buf не выровнять

mittorn ★★★★★
()

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

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 ★★
()
Ответ на: комментарий от alexanius

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

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

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

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

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

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

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

А, точно думал там указатели. Тогда по факту проблем быть не должно, но, как здесь уже написали, правильнее будет memcpy.

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
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.