2014 dxdy logo

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

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




На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:11 
guryev в сообщении #1427671 писал(а):
Нет, их обоих, это же union.
Всё, ребят, расходимся. Это же... UNION! Ну что есть против него какие-то стандарты непонятные? Это ж union! Сам!

 
 
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:29 
Короче говоря, для 4-байтного long инициализация long_value проинициализирует и char_values. Они одного размера и занимают одни и те же байты. Другое дело, если число байт в long'е не 4, а скажем, 8 - тогда этот вариант не сработает - потому у меня и вынесено в #define число байт - для такого случая это надо переопределять. Но в исходной задаче сказано, "работать с целым как с массивом из четырёх однобайтовых чисел" - для восьмибайтовых целых задача по-любому не определена.

 
 
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 20:29 
Аватара пользователя
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 
Вообще - нельзя, а в данной задаче - можно.

 
 
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:05 
Аватара пользователя
Ни в какой задаче нельзя, если хочется иметь хоть какие-то основания считать, что код не сломается от перехода на новую версию компилятора.

 
 
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:09 
Пока условия данной задачи не противоречат свойствам платформы и компилятора, таких оснований нет.

 
 
 
 Re: c++ задача на битовые операции
Сообщение25.11.2019, 21:38 
Аватара пользователя
guryev в сообщении #1427691 писал(а):
Пока условия данной задачи не противоречат свойствам платформы и компилятора, таких оснований нет.
Какое-то странное высказывание - а что, если условия задачи начнут противоречить свойствам компилятора (что это вообще значит?), то появятся основания считать, что код не сломается?

 
 
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 08:32 
Да, это я неправильно понял вашу фразу. В данном случае:
пока условия данной задачи не противоречат свойствам платформы и компилятора, нет оснований считать, что код сломается. Но есть основания считать, что не сломается.

 
 
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 13:04 
Аватара пользователя
Я не знаю, что значит "условия задачи противоречат свойствам платформы". Но оснований считать, что этот код продолжит работать, нет. Кроме разве что доброй воли разработчиков компиляторов, т.е. в случае MSVC какие-то шансы еще есть, а в случае gcc - только если повезет и разработчики не придумают, какую оптимизацию на 0.01% для процессора 1993 года выпуска можно сделать за счет учета этого UB.

 
 
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 14:28 
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 
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 
Аватара пользователя
guryev в сообщении #1427825 писал(а):
Следовательно, поля long_value и char_values, занимающие по 4 байта каждое, размещаются в одной и той же области памяти.
Следовательно, запись в поле long_value заполняет и массив char_values. Аналогично, доступ к байту из массива char_values означает доступ к одному из байт поля long_value.
Вы знаете, что такое UB? Компилятор исходит из предположения, что в вашем коде его нет. И если вы пишете в один член union, и не читаете из него до того момента, пока не прочитаете из другого - то компилятор имеет полное право выкинуть запись.
Вообще он имеет полное право позвать форматирование диска в таком случае, но выкидывание записи вполне может произойти и на практике.

 
 
 
 Re: c++ задача на битовые операции
Сообщение26.11.2019, 17:45 
Как нельзя пользоваться 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 
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 
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  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group