2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:11 
Заслуженный участник


02/08/11
7014
guryev в сообщении #1427671 писал(а):
Нет, их обоих, это же union.
Всё, ребят, расходимся. Это же... UNION! Ну что есть против него какие-то стандарты непонятные? Это ж union! Сам!

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:29 


27/02/09
253
Короче говоря, для 4-байтного long инициализация long_value проинициализирует и char_values. Они одного размера и занимают одни и те же байты. Другое дело, если число байт в long'е не 4, а скажем, 8 - тогда этот вариант не сработает - потому у меня и вынесено в #define число байт - для такого случая это надо переопределять. Но в исходной задаче сказано, "работать с целым как с массивом из четырёх однобайтовых чисел" - для восьмибайтовых целых задача по-любому не определена.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:29 
Заслуженный участник
Аватара пользователя


16/07/14
9216
Цюрих
guryev в сообщении #1427671 писал(а):
Нет, их обоих, это же union.
Вы английский язык понимаете?
Цитата:
if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union


-- 25.11.2019, 20:30 --

Собственно union предназначен для того, чтобы в одной области памяти в разное время хранить разные объекты, использовать его для таких преобразований в С++ нельзя (в новых стандартах С вроде бы можно).

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:58 


27/02/09
253
Вообще - нельзя, а в данной задаче - можно.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:05 
Заслуженный участник
Аватара пользователя


16/07/14
9216
Цюрих
Ни в какой задаче нельзя, если хочется иметь хоть какие-то основания считать, что код не сломается от перехода на новую версию компилятора.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:09 


27/02/09
253
Пока условия данной задачи не противоречат свойствам платформы и компилятора, таких оснований нет.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:38 
Заслуженный участник
Аватара пользователя


16/07/14
9216
Цюрих
guryev в сообщении #1427691 писал(а):
Пока условия данной задачи не противоречат свойствам платформы и компилятора, таких оснований нет.
Какое-то странное высказывание - а что, если условия задачи начнут противоречить свойствам компилятора (что это вообще значит?), то появятся основания считать, что код не сломается?

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 08:32 


27/02/09
253
Да, это я неправильно понял вашу фразу. В данном случае:
пока условия данной задачи не противоречат свойствам платформы и компилятора, нет оснований считать, что код сломается. Но есть основания считать, что не сломается.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 13:04 
Заслуженный участник
Аватара пользователя


16/07/14
9216
Цюрих
Я не знаю, что значит "условия задачи противоречат свойствам платформы". Но оснований считать, что этот код продолжит работать, нет. Кроме разве что доброй воли разработчиков компиляторов, т.е. в случае MSVC какие-то шансы еще есть, а в случае gcc - только если повезет и разработчики не придумают, какую оптимизацию на 0.01% для процессора 1993 года выпуска можно сделать за счет учета этого UB.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 14:28 


27/02/09
253
mihaild в сообщении #1427808 писал(а):
Я не знаю, что значит "условия задачи противоречат свойствам платформы".

guryev в сообщении #1427761 писал(а):
пока условия данной задачи не противоречат свойствам платформы и компилятора,
Для данной задачи это означает, что система и настройки компилятора таковы, что с типом long можно работать, как с массивом из 4-х байтов, в задаче - типа char, то есть, тип long занимает столько же памяти, сколько char[4].
mihaild в сообщении #1427808 писал(а):
Но оснований считать, что этот код продолжит работать, нет.
Основания следующие:
Под union выделяется в данном случае 4 байта (размер наибольшего элемента, в соответствии со стандартом).

Следовательно, поля long_value и char_values, занимающие по 4 байта каждое, размещаются в одной и той же области памяти.

Следовательно, запись в поле long_value заполняет и массив char_values. Аналогично, доступ к байту из массива char_values означает доступ к одному из байт поля long_value.

Это и означает
mmarin в сообщении #1426977 писал(а):
работать с целым числом (long) как с "массивом" из четырех однобайтовых чисел (char)

mihaild в сообщении #1427808 писал(а):
Кроме разве что доброй воли разработчиков компиляторов, т.е. в случае MSVC какие-то шансы еще есть, а в случае gcc - только если повезет и разработчики не придумают, какую оптимизацию на 0.01% для процессора 1993 года выпуска можно сделать за счет учета этого UB.
Это не про данную тему.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 14:55 


09/05/16
138
mihaild в сообщении #1427808 писал(а):
в случае gcc - только если повезет

Справедливости ради, GCC явно разрешает type punning ("Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the code above works as expected."), доопределяя поведение и давая более строгие гарантии, чем требуется по стандарту. Насчёт Clang и MSVC не знаю.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 15:46 
Заслуженный участник
Аватара пользователя


16/07/14
9216
Цюрих
guryev в сообщении #1427825 писал(а):
Следовательно, поля long_value и char_values, занимающие по 4 байта каждое, размещаются в одной и той же области памяти.
Следовательно, запись в поле long_value заполняет и массив char_values. Аналогично, доступ к байту из массива char_values означает доступ к одному из байт поля long_value.
Вы знаете, что такое UB? Компилятор исходит из предположения, что в вашем коде его нет. И если вы пишете в один член union, и не читаете из него до того момента, пока не прочитаете из другого - то компилятор имеет полное право выкинуть запись.
Вообще он имеет полное право позвать форматирование диска в таком случае, но выкидывание записи вполне может произойти и на практике.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 17:45 


29/12/13
306
Как нельзя пользоваться union в с++ , вот: несколько заметок-правил.

По вопросу, оттуда:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
union Pun {
    int x;
    unsigned char c[sizeof(int)];
};

void bad(Pun& u)
{
    u.x = 'x';
    cout << u.c[0] << '\n';       // undefined behavior (1)
}

void if_you_must_pun(int& x)
{
    auto p = reinterpret_cast<unsigned char*>(&x);   // (2)

    cout << p[0] << '\n';                            // OK; better
    // ...
}
 


Цитата:
Expression (1) has two issues. First and foremost, it's undefined behaviour. Second, the type punning is quite difficult to find. This means if you have to use type punning, do it with an explicit cast such as reinterpret_cast in (2). With reinterpret_cast you have at least the possibility to spot afterwards your type punning.


-- 26.11.2019, 18:09 --

upd.

И ещё думаю, что кто задал задачу вполне может ничего не знать про UB, вполне может взамен с++ оказаться "turbo с" 87-ого года, например.
Т.е. чтобы реально помочь ТС, надо точно знать, что они проходили, как проходили и понимать что от них хотят.

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 18:30 


27/02/09
253
Seman в сообщении #1427849 писал(а):
Как нельзя пользоваться union в с++ , вот: несколько заметок-правил.


По вопросу, оттуда:
...............
Тут undefined behavior получится не из-за использования union, а из-за неизвестного порядка байтов, хотя автор об этом и не упоминает. Здесь можно только сказать, что выведется нулевой байт из u.x. Естественно, это может быть как символ 'x', так и 0. То же самое относится и к варианту ниже - с преобразованием типов в функции if_you_must_pun.

Конечно, можно было использовать вместо union просто класс, например, так:

Используется синтаксис C++
class No_Union {
private:
        long value;
public:
        No_Union() {}
        No_Union( long v ): value( v ) {}
        operator long & () { return(value); }
        char & operator [] (size_t idx) { return(((char *)(&value))[idx]); }
};
 
Я выбрал union, чтобы избежать длинного преобразования типа в операторе [], и никак не думал, что это вызовет столько беспокойства :-)

 Профиль  
                  
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 18:59 


29/12/13
306
guryev в сообщении #1427858 писал(а):
Здесь можно только сказать, что выведется нулевой байт из u.x. Естественно, это может быть как символ 'x', так и 0.

Поясните, пожалуйста, чем отличается:
Используется синтаксис C++
u.c[0]
 

от вашего
Используется синтаксис C++
char_values[idx]


И что там с порядком байт, почему у вас с ним все в порядке, а там нет? И откуда по вашей мысли может быть 0?

У вас :
Используется синтаксис C++
        Long_And_Char lg = Long_And_Char(125);
        std::cout << lg[0] << std::endl;
 

Какой байт и откуда выведется?

-- 26.11.2019, 19:11 --

guryev в сообщении #1427858 писал(а):
Конечно, можно было использовать вместо union просто класс, например, так:


Что будет, если значение в idx больше размера long ?
Используется синтаксис C++
        Long_And_Char lg = Long_And_Char(125);
        std::cout << lg[1230] << std::endl;
 

И это не тоже самое, class и union все-таки разные вещи.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 68 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group