LINUX.ORG.RU

язык С в UNIX-like системах


0

0

Уважаемые линуксоиды =) очень прошу объяснить а то я никак не могу сам понять... читаю учебник по С... и другие справочники читал.... но так и не понял... запутался %)

в Unix-подобных системах что ли не такой язык С как везде? вроде ведь C99? но говорят, что куча своих дополнений... %) а от чего они зависят? из-за библиотек? ... меня очень давно уже это интересует....

разные стандарты языка С это как отдельные языки С что ли? %)

очень большая просьба объяснить.... :(

Заранее огромнооооооое спасибо...

anonymous

Ответ на: комментарий от anonymous_incognito

> Так здесь речь не идёт об attribute(packed), а о вполне, если так
можно выразиться, контролируемом создании iov, который опять же
ручками расписали выше.

--- cut ---
struct udphdr hdr;
memset(&hdr, 0, sizeof(hdr));
....
--- cut ---

в netinet/udp.h udphdr в полном соответствии с RFC объявлена как
структура с четырьмя 16ти битными полями -> в силу естественного
выравнивания ей не нужен атрибут packed и sizeof(hdr) прекрасно
работает и без него. а если мы возьмём какой-то другой протокол,
в котором поля не выровнены на слово? тут уже без packed никуда
или же придётся отказаться от sizeof(struct) привлекая внешние
определения размера пакета что явно не фонтан бо рано или поздно
легко рассинхронизоваться на уровне исходников.

да, очевидно, что htons не имеет никакого отношения к packed
и сам по себе packed никак не влияет на endianness и тд. и тп.
по крайней мере мне кажется это очевидным. но судя по тому, куда
занесло анонимное сомнище, это очевидно далеко не всем.

> То есть, возможно, мы просто не поняли друг-друга.

да, скорее всего.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> вполне логично описывать пакеты, передаваемые по сети, в виде структур и принимать/передавать их в приложении соответственно.

Да, но ни в коем случае эти структуры не сериализовать as is! Только через функции, ручками растаскивающие байтики по полям и собирающие поля в байтики, с учетом endianness. А при таком подходе packed не нужен.

svu ★★★★★
()
Ответ на: комментарий от svu

> Да, но ни в коем случае эти структуры не сериализовать as is!
Только через функции, ручками растаскивающие байтики по полям и
собирающие поля в байтики, с учетом endianness.

конечно, кто спорит то. достаточно очевидное наблюдение :)

> А при таком подходе packed не нужен.

#include <netinet/udp.h>

struct udphdr hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.uh_sport = htons(src_port);
hdr.uh_dport = htons(dest_port);
hdr.uh_ulen  = htons(length);
hdr.uh_ulen  = htons(udp_cksum(data, length));

struct iovec iov[2];
iov[0].iov_base = &hdr;
iov[0].iov_len  = sizeof(hdr);
iov[1].iov_base = data;
iov[1].iov_len  = length;
writev(fd, iov, 2);

вопрос: всегда ли будет работать приведённый выше код без
использования packed?

// wbr

klalafuda ★☆☆
()

Ребята, а зачем вы спорите, пытаясь что-то объяснить какому хамоватому типу? Все равно, все останетесь при своих :)

Топикстартеру: С - низкоуровневый язык. Поэтому пытаясь быть ближе к железу, C бывает разным на разных архитектурах. Это by design и это абсолютно нормально. То есть, язык один, но диалекты случаются. На x86/x64 язык C почти везде одинаковый, но у каждого компилятора есть свои примочки.

Хороший стиль программирования - по возможности следовать стандарту и писать "мобильный", т.е. переносимый на разные платформы код. В случае C это иногда непросто, но возможно :) А всяческие приблуды типа __attribute__ только запутывают дело. Но жить можно.

dave ★★★★★
()
Ответ на: комментарий от klalafuda

> вопрос: всегда ли будет работать приведённый выше код без использования packed?

Ну, на всех существующих 32 и 64 - битных системах оно будет работать. Вижу тут только стандартные структуры (причем в Линуксе udphdrс из netinet/udp.h с Линукс-специфичными u_int16_t), ни одна из которых никаких packed атрибутов не имеет!

А насчет iov[0].iov_len = sizeof(hdr); -- оно просто не проканает на экзотических архитектурах. В RFC 768 (на который ссылается netinet/udp.h) про структуры нет _ни_слова_! Весь netinet/udp.h никакого отношения к стандартам не имеет, реализация его линукс-специфична и заточена только под конкретные архитектуры -- тем не менее, никакими packed там не пахнет...

Die-Hard ★★★★★
()
Ответ на: комментарий от klalafuda

> вопрос: всегда ли будет работать приведённый выше код без использования packed?

Возможно, не всегда. Но именно потому что он сериализует структуры, а не массивы байтов.

svu ★★★★★
()
Ответ на: комментарий от dave

> Ребята, а зачем вы спорите, ...

Дело в том, что бурные дискуссии по поводу сериализации структур с использованием packed происходят тут где-то раз в году с завидным постоянством. Аргументы повторяются по кругу, странно, что на сей раз не вспомнили про то, как быстро и удобно упакованные структуры ммапить в файлы...

Я лично просто не понимаю, зачем вообще нужны упакованные структуры (разве что забить на производительность и переносимость и прямо с ними и работать). К сожалению, все чаще люди, насмотревшись x86 линукс - специфических хедеров, покопавшись в ядре и написав пару-тройку драйверов, отказываются понимать проблему. Самое печальное, что многие из них потом становятся разработчиками популярного софта, и следующие поколения ньюбов уже ссылаются на авторитет этих разработчиков...

Самое печальное, что обсуждать это стало невозможно: любое обсуждение немедленно сворачивает в сторону агрессивной перепалки.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.