The OpenNET Project / Index page

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

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"OpenNews: Основы написания переносимого кода"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Разговоры, обсуждение новостей (Public)
Изначальное сообщение [ Отслеживать ]

"OpenNews: Основы написания переносимого кода"  
Сообщение от opennews (??) on 26-Мрт-08, 11:18 
Сергей Каличев представил перевод (http://lex.iki.rssi.ru/~serj/docs/lemmings_ru/lemmings_ru.html) статьи с описанием типичных проблем, возникающих при написании переносимого кода, некоторые из проблемы очевидны, но ошибки, с ними связанные, продолжают регулярно появляться в реальном коде.

URL: http://lex.iki.rssi.ru/~serj/docs/
Новость: https://www.opennet.ru/opennews/art.shtml?num=14963

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Основы написания переносимого кода"  
Сообщение от Аноним (??) on 26-Мрт-08, 11:18 
Куча грамматических ошибок :(
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Основы написания переносимого кода"  
Сообщение от Konwin email(ok) on 26-Мрт-08, 11:19 
Мне вот интересно - написание переносимого кода описывается уже лет 20 так - зачем писать что-то еще?
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Основы написания переносимого кода"  
Сообщение от Ivan_Dives (ok) on 26-Мрт-08, 11:43 
revision 1.8
date: 2001/11/29 22:55:57; author: ross; state: Exp; lines: +1 -6
Delete the old BUGS section entry:
> On the VAX bytes are handled backwards from most everyone else in
> the world. This is not expected to be fixed in the near future.

не понял при чём тут вакс. Это, насколько я знаю, компьютеры, которые использовались ещё в 1970... так к чему они здесь?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Основы написания переносимого кода"  
Сообщение от whirlwind on 26-Мрт-08, 12:12 
это такой тончайший юмор, в конце статьи пояснение:
>В названии (``Fighting the lemmings'') нет какого-то особого смысла. Раньше мы говорили >``весь мир VAX'', а теперь весь мир -- i386 и везде работает linux. Все авторы просто >следуют за этим ``леммингом -- вожаком'' и пишут (а ещё хуже -- тестируют) код >исключительно под i386/linux.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Основы написания переносимого кода"  
Сообщение от Ivan_Dives (ok) on 26-Мрт-08, 12:15 
>revision 1.8
>date: 2001/11/29 22:55:57; author: ross; state: Exp; lines: +1 -6
>Delete the old BUGS section entry:
>> On the VAX bytes are handled backwards from most everyone else in
>> the world. This is not expected to be fixed in the near future.
>
>не понял при чём тут вакс. Это, насколько я знаю, компьютеры, которые
>использовались ещё в 1970... так к чему они здесь?

всё, понял

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "OpenNews: Основы написания переносимого кода"  
Сообщение от послушайте on 26-Мрт-08, 12:17 
> Хотя портирование на NetBSD/sparc64 практически является таким тестом ;-)

собственно я сейчас там на sparc64.

и вот такая конструкция:
uint8_t a[] = { 41, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 3 };

uint32_t u32 = *((uint32_t *) &a[1]);

дает Bus error.

это просто пример, пришлось определить (не дословно):
#define LOAD32(p, b)    b=(((((((uint32_t)(((b) & 0) | *(((uint8_t *)p) + 3)) << 8) | *(((uint8_t *)p) + 2)) << 8) | *(((uint8_t *)p) + 1)) << 8) | *((uint8_t *)p))

но это думаю медленно, можно как нибудь оптимизировать?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "OpenNews: Основы написания переносимого кода"  
Сообщение от a (??) on 26-Мрт-08, 14:15 
typedef union {
  char a[4];
  uint32_t b;
} c_t;

c_t c;

c.a[0] = 41;c.a[1] = 0;c.a[2] = 0;c.a[0] = 0;

printf("%u", c.b);

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "OpenNews: Основы написания переносимого кода"  
Сообщение от Аноним (??) on 26-Мрт-08, 18:06 
и вот такая конструкция:
uint8_t a[] = { 41, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 3 };

uint32_t u32 = *((uint32_t *) &a[1]);

дает Bus error.


ЧУВАААК, почитай доки к gcc, в частности non-bugs.txt или как там. ЗАПРЕЩЕНО такое делать.
Чтобы это заработало у gcc есть ключик, но они говорят что в стандартах на C такое поведение не описано, поэтому сосямба. Ну и ничего что этот код совершенно непереносим из-за endianess?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "OpenNews: Основы написания переносимого кода"  
Сообщение от послушайте on 27-Мрт-08, 10:34 

>ЧУВАААК, почитай доки к gcc, в частности non-bugs.txt или как там. ЗАПРЕЩЕНО
>такое делать.
>Чтобы это заработало у gcc есть ключик, но они говорят что в
>стандартах на C такое поведение не описано, поэтому сосямба. Ну и
>ничего что этот код совершенно непереносим из-за endianess?

ЧУВАК это просто ПРИМЕР чтобы смысл в чем ОШИБКА показать..

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "OpenNews: Основы написания переносимого кода"  
Сообщение от Аноним (??) on 26-Мрт-08, 20:02 
> и вот такая конструкция:
> uint8_t a[] = { 41, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 3 };
> uint32_t u32 = *((uint32_t *) &a[1]);
> дает Bus error.

И это ты типа удивлен? `Вон из профессии!' (C)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "OpenNews: Основы написания переносимого кода"  
Сообщение от очень жаль on 27-Мрт-08, 10:30 
ну чи то разорались? умные все что ли?
пытаюсь перенести игрушку одну с DOS с РЕСУРСАМИ это вам вообще о чем нибудь говорит?
а
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "OpenNews: Основы написания переносимого кода"  
Сообщение от очень жаль on 27-Мрт-08, 10:31 
для тех кто все еще ТРАМВАЕ - РЕСУРСЫ БИНАРНЫЕ
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Основы написания переносимого кода"  
Сообщение от pavlinux email(ok) on 26-Мрт-08, 23:26 
Сергей Каличев - статья полезная, перевод нужный...

Давеча, пролетало, https://www.securecoding.cert.org/confluence/display/seccode...

Уже можете переводить :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Основы написания переносимого кода"  
Сообщение от vle email on 27-Мрт-08, 11:10 
Мда, "К сожалению, NetBSD заботится о двоичной совместимости".
Как раз к счастью NetBSD заботиться о бинарной совместимости, и очень жаль тех, кто о ней не заботится.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Основы написания переносимого кода"  
Сообщение от Аноним (??) on 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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Гм..."  
Сообщение от gena2x on 12-Фев-09, 14:34 
>Как можно перепутать обращение к невыравненным данным (по их размеру) с проблеммой strict алиасинга в (я бы посоветовал gena2x попробовать свой тест на ветке 2.x.x - 3.x.x например )?

Пример приводился для x86/linux/gcc. sizeof(int)==sizeof(long) - о каком выравнивании (по размеру) речь?

Да, надо было дописать что -fstrict-aliasing только в четвертой ветке по умолчанию включается в -O2.

>Wstrict-aliasing=2 тогда все проблемные места будет сразу видно:

Не все, к сожалению, посему придётся разобраться в проблеме.

> То дает инструкцию компилятору считать что все указатели разных типов указывают на непересекающиеся области памяти.

Почти все, char* например - исключение.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




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

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