Re: memory align requirements (C99)
От: Abyx Россия  
Дата: 20.05.15 17:43
Оценка: 4 (1)
Здравствуйте, Zhendos, Вы писали:

Z>Также интересно, что думает об этом C11,C++11, C++14?


В C++ дела обстоят иначе.
можно кастовать Т1* в Т2* если alignof(T1) >= alignof(T2)
иначе *значение результата каста не определено*, т.е. в самом касте неопределенного поведения нету, UB появляется только если разыменовать результат каста
In Zen We Trust
Re[2]: memory align requirements (C99)
От: v_andal Германия  
Дата: 21.05.15 07:08
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, Zhendos, Вы писали:


Z>>Также интересно, что думает об этом C11,C++11, C++14?


A>В C++ дела обстоят иначе.

A>можно кастовать Т1* в Т2* если alignof(T1) >= alignof(T2)
A>иначе *значение результата каста не определено*, т.е. в самом касте неопределенного поведения нету, UB появляется только если разыменовать результат каста

Собственно, это то же самое. И в С выравнивание для величины должно быть больше или равным требуемому для этой величины. Это автоматически вытекает из математики для выравнивания.
memory align requirements (C99)
От: Zhendos  
Дата: 20.05.15 08:09
Оценка:
Вопрос навеян:

6.3.2.3/7:

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.


Допустим есть
int *p_int; void *p_void;
.
Как узнать допустимые значения для p_void в
p_int = p_void;
?

допустим мы говорим о clang/gcc/icc + linux + amd64.

Для gcc мне ответили (разработчики gcc), что в случае с gcc/linux/amd64,
они хотят 4 байта выравнивание, но не пояснили где в документации
gcc об этом можно прочитать. В ABI, который они реализуют для amd64,
сказано, что misaligned доступ не должен вызывать проблем, поэтому
они как бы усили требования по срванению с ABI.

Также интересно, что думает об этом C11,C++11, C++14?
Re: memory align requirements (C99)
От: v_andal Германия  
Дата: 20.05.15 12:31
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Вопрос навеян:

Z>

Z>6.3.2.3/7:

Z>A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.


Z>Допустим есть
int *p_int; void *p_void;
.

Z>Как узнать допустимые значения для p_void в
p_int = p_void;
?


Z>допустим мы говорим о clang/gcc/icc + linux + amd64.


Z>Для gcc мне ответили (разработчики gcc), что в случае с gcc/linux/amd64,

Z>они хотят 4 байта выравнивание, но не пояснили где в документации
Z>gcc об этом можно прочитать. В ABI, который они реализуют для amd64,
Z>сказано, что misaligned доступ не должен вызывать проблем, поэтому
Z>они как бы усили требования по срванению с ABI.

Z>Также интересно, что думает об этом C11,C++11, C++14?


Не совсем понято, в чём собственно проблема? Нужно узнать alignment для хранения int? В gcc есть оператор __alignof__. Пишешь
printf("%zu\n", __alignof__ (int));
и узнаёшь значение для твоей платформы. Само собой, на разных платформах это значение может быть разным, поэтому если это и прописано, то скорее в документации на платформу, чем в С-стандартах.
Re: memory align requirements (C99)
От: sokel Россия  
Дата: 20.05.15 14:07
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>misaligned доступ не должен вызывать проблем, поэтому

Z>они как бы усили требования по срванению с ABI.

Где-то не вызывает проблем, где-то вызывает, поэтому в общем случае the behavior is undefined.
Re[2]: memory align requirements (C99)
От: Zhendos  
Дата: 20.05.15 16:56
Оценка:
Здравствуйте, v_andal, Вы писали:


Z>>Допустим есть
int *p_int; void *p_void;
.

Z>>Как узнать допустимые значения для p_void в
p_int = p_void;
?



_>Не совсем понято, в чём собственно проблема? Нужно узнать alignment для хранения int? В gcc есть оператор __alignof__. Пишешь
printf("%zu\n", __alignof__ (int));
и узнаёшь значение для твоей платформы. Само собой, на разных платформах это значение может быть разным, поэтому если это и прописано, то скорее в документации на платформу, чем в С-стандартах.


Проблема что на x86 32 бита он выдает 4, хотя я видел
полно говнокода, который на x86 приводит "char *", выравненный
хрен знает как, к "int *" и начинает работать.

Получается весь этот код невалидный даже для той
платформы, для которой он писался (платформа = ОС+компилятор(gcc)+CPU(x86))?
Re[2]: memory align requirements (C99)
От: Zhendos  
Дата: 20.05.15 16:57
Оценка:
Здравствуйте, sokel, Вы писали:

S>Здравствуйте, Zhendos, Вы писали:


Z>>misaligned доступ не должен вызывать проблем, поэтому

Z>>они как бы усили требования по срванению с ABI.

S>Где-то не вызывает проблем, где-то вызывает, поэтому в общем случае the behavior is undefined.


Так я привел конкретную платформу, мне для нее и нужно понять,
"вообще" мне не интересно.
Re[3]: memory align requirements (C99)
От: v_andal Германия  
Дата: 21.05.15 07:21
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, v_andal, Вы писали:



Z>>>Допустим есть
int *p_int; void *p_void;
.

Z>>>Как узнать допустимые значения для p_void в
p_int = p_void;
?



_>>Не совсем понято, в чём собственно проблема? Нужно узнать alignment для хранения int? В gcc есть оператор __alignof__. Пишешь
printf("%zu\n", __alignof__ (int));
и узнаёшь значение для твоей платформы. Само собой, на разных платформах это значение может быть разным, поэтому если это и прописано, то скорее в документации на платформу, чем в С-стандартах.


Z>Проблема что на x86 32 бита он выдает 4, хотя я видел

Z>полно говнокода, который на x86 приводит "char *", выравненный
Z>хрен знает как, к "int *" и начинает работать.


Собственно под словом "платформа" я имел ввиду железо на котором выполняется программа. Извиняюсь, если неверно использовал термин. Однажды мне пришлось писать программу для процессора Alpha. Будучи ещё нубом, я не мудрствуя лукаво указывал int * в середину байтового буфера. На Intel всё это работало. А на Alpha в общем-то тоже работало, но заваливало системные логи сообщениями, что произошло обращение к не выравненной области памяти. Так я и узнал, что лучше лишний раз
memcpy(&int_val, char_ptr, sizeof(int_val));
сделать, либо аккуратно строковый буфер организовывать.

В общем, эти требования по выравниванию возникают из-за требований железа. Чтобы не приходилось в программе выяснять, на каком железе идёт работа, предлагается сразу выравнивать память. Не хочешь выравнивать — попадаешь в серую зону undefined behavior, где-то работать будет, а где-то нет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.