The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Основы написания переносимого кода"
Отправлено Аноним, 28-Мрт-08 12:56 
  Статья на слабую тройку. Перечислено только около 10% типичных ошибок программистов. Автор похоже коммитит код в NetBSD и наивно считает ее самой портабельной, да и еще незаслуженно обижает разработчиков под Linux, которая BTW поддерживает в стабильной ветке на 6 CPU архитектур больше чем NETBSD и как минимум в два раза больше платформ и MMU BSP.
----------------------------------------------------
Недопонимание переводчика:

О приведении типов указателей
В главе о приведении типов указателей попалась одна непонятная фраза: You are allowed to cast to the ``right'' type of an object when assigning via a pointer, so the compiler assumes all variables of the casted-to type might have changed. Вот комментарии автора по этому поводу:

<<Скажем, у вас есть поток байтов, который включает в себя некоторый участок, и вы хотите обратиться к этому участку, как к структуре. Поток байтов не имеет выравнивания. Для указателя на байт используется char* или void*. Теперь, если привести тип указателя к типу struct* (указатель на вашу структуру), компилятор будет считать указатель допустимым, включая все требования по выравниванию, относящиеся к указателям на вашу структуру.

Это также справедливо в случае, если вы сперва выполнили приведение типа указателя, а потом использовали memcpy() для копирования содержимого структуры.

Однако, если вы выполните memcpy(), т.е. скопируете данные по указателю с неприведённым типом void*/char* в локальную типизированную структуру, то компилятор не станет делать никаких предположений и всё будет работать нормально.>>

Этот комментарий не до конца прояснил смысл фразы. Более понятно стало после комментария от gena2x. Речь идёт об особенностях оптимизации. Был приведён следующий пример:

$ cat > test.c
#include <stdio.h>

void f(int *i, long *l) {
    printf("1.v=%ld\n", *l);
    *i = 11;
    printf("2.v=%ld\n", *l);
}

int main() {
    long b = 10;
    f((int*)&b, &b);
    printf("3.v=%ld\n", b);
}

$ gcc -O2 test.c -o test
$ ./test
1.v=10
2.v=10
3.v=11

Неожиданное значение ``2. v=10''. Обратите внимание, при компиляции использовалась оптимизация -O2. Если оптимизацию не использовать, то вывод будет другим:

$ gcc test.c -o test
$ ./test
1.v=10
2.v=11
3.v=11

При использовании оптимизации компилятор ``не заметил'', что значение *l изменилось. Если же строку ``*i = 11;'' заменить на ``*(long *)i = 11;'', то компилятор сделает предположение, что могли измениться все значения по указателям, имеющим тип long * (тип к которому приводили), и соответственно при использовании *l будет получено уже новое значение (``2.v=11'').

----------------------------------------------------------------------------
Автор перевода и gena2x жгут...
Как можно перепутать обращение к невыравненным данным (по их размеру) с проблеммой strict алиасинга в (я бы посоветовал gena2x попробовать свой тест на ветке 2.x.x - 3.x.x например )?
gcc-3.3.6 -O3 test.c
1.v=10
2.v=11
3.v=11
Результат правильный... На других 4.x.x в основном неправильный...

А если так gcc -O3 -fno-strict-aliasing test.c
то всегда то что ожидалось :)

  Да вы правильно догадались начиная с 4.x.x -O2 подразумевает -fstrict-aliasing                                                           , что дает инструкцию компилятору считать что все указатели разных типов указывают на непересекающиеся области памяти.

Таким образом рекомендуется при использовании оптимизации в GCC обязательно указывать флаг: -Wstrict-aliasing=2 тогда все проблемные места будет сразу видно:
$ gcc -O3 test.c -Wall -Wstrict-aliasing=2
test.c: In function ‘main’:
test.c:11: warning: dereferencing type-punned pointer will break strict-aliasing rules

Мои CFLAGS обычно включают седующие флаги:
-Wall -Wstrict-prototypes -Wcast-qual -Wcast-align -Wbad-function-cast -Wconversion -Wstrict-aliasing=2

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
  Введите код, изображенный на картинке: КОД
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру