metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-04-28 01:58 pm

libev, забавное

В бабуинанедолбеанедебиане gcc -O2 при компиляции примера работы с libev кидает кучу warnings типа "testev.c:58: warning: dereferencing type-punned pointer will break strict-aliasing rules"

Автор на вопросы на эту тему псит, как команда из 100500 айседов и авторов firebird вместе взятых, в стиле "вы тупые, используйте компилятор C для компиляции C, идите нахрен, это всего лишь warning".

http://comments.gmane.org/gmane.comp.lib.ev/907
http://lists.schmorp.de/pipermail/libev/2010q1/000912.html

собственно патчик: http://lists.schmorp.de/pipermail/libev/attachments/20100218/3c4aaf8c/attachment.txt

[identity profile] tzirechnoy.livejournal.com 2012-04-28 11:05 am (UTC)(link)
А зачем тебя в libev понесло?

Это, типа, предыдущий вопрос так развился?

[identity profile] metaclass.livejournal.com 2012-04-28 11:06 am (UTC)(link)
Да, читаю документацию по ней.

[identity profile] avnik.livejournal.com 2012-04-28 11:32 am (UTC)(link)
Автор козел.
Сишный код должен компилироваться с -Wall -Werror (И желательно не только gcc, но и clang'ом тоже)

[identity profile] blacklion.livejournal.com 2012-04-28 11:35 am (UTC)(link)
-ansi -pedantic

Но даже тогда gcc ловит не всё.

[identity profile] mend0za.livejournal.com 2012-04-28 11:49 am (UTC)(link)
если хочется такого грёбанного вуду - в статические и динамические анализаторы кода.

Те которые "строят модэл" или "по списку известных тараканов мы вам предъявим обвинения".

[identity profile] dair-spb.livejournal.com 2012-04-28 12:04 pm (UTC)(link)
-ansi это имхо перебор для реальных, а не академических задач (мне реально проще писать for (int i = 0; ...) чем int i; for (i = 0; ...)). Pedantic рулит, да.

[identity profile] blacklion.livejournal.com 2012-04-28 01:22 pm (UTC)(link)
Ты стандарт-то читал? ;-) Первый вариант допустим в C99.
Но, например, VLA не допустимы ни в какой версии C++, а g++ их пропускает даже с педантиком.

[identity profile] dair-spb.livejournal.com 2012-04-28 01:24 pm (UTC)(link)
> Ты стандарт-то читал?
Пробовал, но там сюжет запутанный и действующих лиц много, как в телефонном справочнике.

> VLA не допустимы ни в какой версии C++, а g++ их пропускает даже с педантиком.
А, если про это, тогда да.

[identity profile] blacklion.livejournal.com 2012-04-28 01:26 pm (UTC)(link)
Ну я просто к тому, что авторы gcc/g++ тоже, похоже, стандарт не дочитали.

[identity profile] kiryl.livejournal.com 2012-04-28 01:39 pm (UTC)(link)
Сам ты не читал. Скажи -std=c++98 и будет тебе то что ты хочешь. -pedantic энфорсит указаный стандарт. gnu++98, по умолчанию. А про VLA есть гнушное расширение, которое gnu++98 включает.

[identity profile] blacklion.livejournal.com 2012-04-28 01:40 pm (UTC)(link)
А что делает -ansi? Мне казалось оно как раз должно переключать стандарт, как и -std= но короче, на последний ansi. Нет?

[identity profile] kiryl.livejournal.com 2012-04-28 01:44 pm (UTC)(link)
Да, это алиас к -std=c++98.

Вот про "не читали" не нужно было.

[identity profile] blacklion.livejournal.com 2012-04-28 01:45 pm (UTC)(link)
Ну так вот у меня с -ansi -pedantic компилирует. Правда, с ворнингом.

[identity profile] blacklion.livejournal.com 2012-04-28 01:51 pm (UTC)(link)
Хм. Забавно. Очень зависит от версии — таки некоторые версии (посвежее) с -pedantic дают ошибку, версии постарее — ворнинг.

[identity profile] kiryl.livejournal.com 2012-04-28 01:56 pm (UTC)(link)
-Werror=vla

[identity profile] ihar hrachyshka (from livejournal.com) 2012-04-28 02:28 pm (UTC)(link)
-ansi
In C mode, this is equivalent to -std=c90. In C++ mode, it is
equivalent to -std=c++98.

[identity profile] blacklion.livejournal.com 2012-04-28 01:43 pm (UTC)(link)
Т.е. я был уверен, что -ansi для g++ это алиас -std=c++98, а для gcc — -std=c99. Значит это мне доку читать надо.

[identity profile] theiced.livejournal.com 2012-04-28 02:15 pm (UTC)(link)
с си у них всё хорошо. а стандарт на крестики настолько говно что его и читать не имеет смысла.

[identity profile] avnik.livejournal.com 2012-04-28 12:29 pm (UTC)(link)
clang вроде ловит больше.

[identity profile] blacklion.livejournal.com 2012-04-28 01:23 pm (UTC)(link)
Да, пора на него переползать.

[identity profile] kiryl.livejournal.com 2012-04-28 01:05 pm (UTC)(link)
Патчик говно. Он только прячет warning.

А у автора libev ебанутый code style. Какие-то многоуровневые typedef'ы и тонны макросов.

[identity profile] metaclass.livejournal.com 2012-04-28 01:12 pm (UTC)(link)
Патч да, кривой.
Я там весь тред прочитал, автор невменяем, причину warning пока я не понял.
макрос раскрывается в конструкцию:

do {
((ev_watcher *)(void *)(&stdin_watcher))->active =
((ev_watcher *)(void *)(&stdin_watcher))->pending = 0;
((ev_watcher *)(void *)((&stdin_watcher)))->priority = (0);
((&stdin_watcher))->cb = (stdin_cb);
} while (0);

((ev_watcher *)(void *)(&stdin_watcher)) упорно вызывает warning, хотя вроде компилятору явно указано, что такие наши намерения.

[identity profile] kiryl.livejournal.com 2012-04-28 01:29 pm (UTC)(link)
Какого типа stdin_watcher? Про strict aliasing rules в курсе?

И, да, gcc'шная эвристика бывает сбоит. False positive warning на тему strict aliasing случается.

[identity profile] metaclass.livejournal.com 2012-04-28 01:39 pm (UTC)(link)
typedef struct ev_watcher
{
int active; int pending; int priority; void *data;
void (*cb)(struct ev_loop *loop, struct ev_watcher *w, int revents);
} ev_watcher;


typedef struct ev_watcher_list
{
int active; int pending; int priority; void *data;
void (*cb)(struct ev_loop *loop, struct ev_watcher_list *w, int revents);
struct ev_watcher_list *next;
} ev_watcher_list;


typedef struct ev_io
{
int active; int pending; int priority; void *data;
void (*cb)(struct ev_loop *loop, struct ev_io *w, int revents);
struct ev_watcher_list *next;

int fd;
int events;
} ev_io;

((ev_watcher *) (void *) (&watcher))->active=17; - показывает warning

собственно, эвристика формально права - структуры разные(т.к. определены в ev.h через развертывание макросов, а не вложение одной структуры в другую.

[identity profile] kiryl.livejournal.com 2012-04-28 02:01 pm (UTC)(link)
Реальной проблемы тут не будет. Проще всего "пофиксить" с -fno-strict-aliasing, раз писать нормально не умеет.

[identity profile] blackyblack.livejournal.com 2012-04-28 01:33 pm (UTC)(link)
Автор читает лекции про си, но так и не объясняет, нахрена писать такой код. Наверное это мега оптимизация...

[identity profile] metaclass.livejournal.com 2012-04-28 01:42 pm (UTC)(link)
Автор, по-моему, все таки не прав, а вот gcc прав. Структуры формально разные.

[identity profile] blackyblack.livejournal.com 2012-04-28 01:45 pm (UTC)(link)
Дак я верю, что gcc прав. Нахрена делать то так? Для таких вещей memcpy есть.

[identity profile] metaclass.livejournal.com 2012-04-28 02:20 pm (UTC)(link)
для таких вещей есть более гуманный вариант: положить общую часть структуры в виде собственно поля в начале всех "унаследованных" структур, что не вызывает warning.

[identity profile] vaddimka.livejournal.com 2012-04-29 01:48 pm (UTC)(link)
элайасинг забавная штука
причем, афаик еще в 2008-й студии такие оптимизации отсутствовали
(тем не менее, зачастую то что собирает последняя студия работает заметно шустрее того что собирает gcc)
проще не пытаться избавиться от ворнингов, а реально разобраться почему это компилятор считает что правила нарушены, в большинстве случаев эти ворнинги ошибочны

[identity profile] metaclass.livejournal.com 2012-04-29 03:07 pm (UTC)(link)
В данном случае, хотя код и работает, эвристика gcc выдает warning вполне законно. Автор libev - буйный идиот.