LINUX.ORG.RU

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


0

0

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

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

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

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

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

anonymous

> в Unix-подобных системах что ли не такой язык С как везде?

Входной язык компилятора разный везде (везде есть свои дополнения), не только в UNIX.

> вроде ведь C99?

С99 - это стандарт, хотя его не все поддердживают. Современный GCC - поддерживает.

tailgunner ★★★★★
()

Такой же как везде.

anonymous
()
Ответ на: комментарий от generatorglukoff

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

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

а такие приложения как, например, Pidgin, Perl (интерпретатор сам в смысле).... с использованием какого стандарта написаны? :)

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

> жаль, нету всех этих дополнений GCC.

дополнения gcc никакого отношения к юниксу не имеют. И забивать ими голову не нужно.

к юниксу имеют отношение дополнительные библиотечные функции и системные вызовы -- про них написано в манах и здесь: http://www.unix.org/single_unix_specification/

dilmah ★★★★★
()

Чем меньше будешь использовать особенности компилятора и расширения, не описанные в стандартах, тем меньше у тебя будет геммороя в будущем.

Sancho_s_rancho
()
Ответ на: комментарий от BigBiker

Спасибо огромное всем :)

и еще вопрос...

а знаменитые приложения типа Пиджина, links и т.д. используют особенности компилятора? %)

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

> а знаменитые приложения типа Пиджина, links и т.д. используют особенности компилятора? %)

знаменитый робот Томми использовал особенности компилятора

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

> Ядро использует. Знаменитые приложения - обычно нет.

да повсеместно. достаточно поискать на предмет __attribute__. из того, что распаковано и попалось под руку: binutils, gdb, cairo, doxygen, fontconfig, freetype, libidn, libpng, openvpn etc etc.

другое дело, что такие фишки как правило обёрнуты в #ifdef __GNUC__ и иже с ними, i.e. при грамотном использовании на переносимость кода между компиляторами влиять не должно.

// wbr

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

> другое дело, что такие фишки как правило обёрнуты в #ifdef __GNUC__ и иже с ними, i.e. при грамотном использовании на переносимость кода между компиляторами влиять не должно.

Да, но писать, поддерживать и тестировать придется больше кода...

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

>да повсеместно...

Увы, согласен -- мрачная действительность...

Но в 99% случаев это не оправдано. ИМХО (!) это следствие нашествия ньюбов, инспирированного и активно поддерживаемого M$.

:-)

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

> Но в 99% случаев это не оправдано. ИМХО (!) это следствие нашествия ньюбов, инспирированного и активно поддерживаемого M$.

ну почему же неоправданно? на вскидку, подавляющее большинство аттрибутов ставится в трех случаях:

1. __attribute__((packed))
2. __attribute__((format(__printf__ ...)))
3. __attribute__((section ...))

штатных средств по борьбе с выравниванием структур нет и тут уж каждый ммм... может как он хочет. кто через прагмы а кто через атрибуты.

что касается format/printf - очень мощьная вещь. да, можно натравить внешний линтер, но если есть встроенный - почему нет. зато без проверки можно поиметь очень и очень много геморою. это не проблема конкретного компилятора, это скорее исторически сложившаяся практика printf-like.

расстановка в секции то-же иногда встречается и то-же бывает нужна [хотя существенно реже]. и без implementation dependant вещей тут то-же никуда.

ну и остальное по мелочи.

// wbr

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

> 4.2 - Не полностью мдауж... разочаровался я в С с его стандартами....

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

> ну почему же неоправданно?

Ну, вааще! :-)

За 1) просто 10 лет расстрела на месте! (Не хочу спорить -- много раз тут обсуждалось).

2) -- ГНУтая специфика, ИМХО абсолютно лишняя. Если кто не осилил, как без этого обойтись, то нефиг вообще программировать.

3) -- совершенно не представляю, для чего оно может понадобится... Такие вещи пишутся на ассемблере!

Конечно, можно покопаться в мануалах и для каждой версии компилятора наваять на интринсиках нечто такое, что обычно без ассемблера невозможно. Оно будет работать процентов на 5 быстреее (впрочем, на реальных задачах, а не на тестах, скорее всего, МЕДЛЕННЕЕ), и на 100% непереносимо между версиями компилятора дистанцией в полгода...

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

>2) -- ГНУтая специфика, ИМХО абсолютно лишняя. Если кто не осилил, как без этого обойтись, то нефиг вообще программировать.

Не согласен. Дополнительная проверка со стороны компилятора не помешает. Все ошибаются.

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

> За 1) просто 10 лет расстрела на месте! (Не хочу спорить -- много раз тут обсуждалось).

1. тем не менее, интересно было бы услышать ваши варианты для работы с тесно упакованными бинарными структурами. пример - сетевые пакеты.

2. не поделитесь секретом - как? помимо "аккуратного кодирования".

ps: я конечно подумываю бросить всю эту хрень к чёртовой матери бо за десять с гаком лет уже как-то подустало, но не думал, что последняя капля будет столь оригинальной.

// wbr

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

> 1. тем не менее, интересно было бы услышать ваши варианты для работы с тесно упакованными бинарными структурами. пример - сетевые пакеты.

а как packed решает эту проблему? Как он решает endianness целых, формат флоатов? Руками все равно сериализовать нужно.

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

>> 1. тем не менее, интересно было бы услышать ваши варианты для
работы с тесно упакованными бинарными структурами.
пример - сетевые пакеты.

> а как packed решает эту проблему?

#include <stdint.h>
#include <stdio.h>

struct s1 {
    uint32_t f1;
    uint8_t  f2;
    uint8_t  f3;
};

struct s2 {
    uint32_t f1;
    uint8_t  f2;
    uint8_t  f3;
} __attribute__((packed));

int
main(void)
{
    printf("s1=%lu s2=%lu\n",
        sizeof(struct s1),
        sizeof(struct s2));
    return 0;
}

$ cc -Wall -Werror -Os test.c
$ ./a.out
s1=8 s2=6

$ gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

> Как он решает endianness целых, формат флоатов?

мне почему то кажется, что вы прекрасно знаете очевидный ответ
на этот вопрос. зачем спрашивать :-?

> Руками все равно сериализовать нужно.

с нетерпением жду RFC791, 0768 и 793 на базе XML. как появятся можно
будет вернуться к этому вопросу. но, боюсь, не раньше.

// wbr

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

> 1. тем не менее, интересно было бы услышать ваши варианты для работы с тесно упакованными бинарными структурами. пример - сетевые пакеты.

Мое мнение -- упакованных структур следует избегать, это всегда можно сделать без потерь.

> 2. не поделитесь секретом - как? помимо "аккуратного кодирования".

Никак! :-) Это ИМХО просто не нужно.

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

> Мое мнение -- упакованных структур следует избегать, это всегда можно сделать без потерь.

приведя к практике будет звучать a'la "не работать с упакованными бинарными данными". хороший конечно совет :)

> Никак! :-) Это ИМХО просто не нужно.

ну что же, удачи в бою. мин на всех хватит с избытком :)

// wbr

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

> приведя к практике будет звучать a'la "не работать с упакованными бинарными данными".

Нет, между "упакованными бинарными данными" и "упакованными структурами" есть принципиальная разница!

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

1% случаев, когда это оправданно - вычислимый goto для прямого шитого кода, очень удобное расширение в gcc, позволяет эффективные VM реализовывать. Пример - интерпретатор байткодов в ocaml.

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

> тем не менее, интересно было бы услышать ваши варианты для работы с тесно упакованными бинарными структурами. пример - сетевые пакеты.

Ручная упаковка/распаковка. Всё равно endianess везде разный, не все процессоры невыровненный доступ поддерживают, так что на Сишных структурах такое будет только конченный урод делать.

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


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

// wbr

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

> За 1) просто 10 лет расстрела на месте! (Не хочу спорить -- много раз > тут обсуждалось).

не соглашусь, иногда без упакованных структур не обойтись
в качестве примера могу привести драйвер NIC
NIC работает с дескрипторами колец _определенного_ формата
формат специфицирован с точностью до разряда
любое выравнивание в данном случае приведен к неккоректной работе (в лучшем случае)

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

За использование в такой ситуации структур надо убивать, с особой жестокостью и цинизмом.

У тебя ручонки не отвалятся, если ты сам байтики как следует упакуешь.

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

> За использование в такой ситуации структур надо убивать, с особой 
> жестокостью и цинизмом.

боюсь, один останешься

> У тебя ручонки не отвалятся, если ты сам байтики как следует упакуешь.

смысл? 

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

> смысл?

Я не вполне одобряю чересчур резкие высказывания предыдущего анонимуса, но должен заметить, что удивительно как иногда не понимаются элементарные, в общем-то вещи.

Когда ты сам ручками пакуешь и распакуешь, ты можешь правильно учесть и endianess и выравнивания данных и размер типов. Запихав всё в структуру, ты гарантировано наживаешь проблемы при другом endianess.

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

> боюсь, один останешься

Не боись. На самом деле таких косолапых кодеров, как ты, не очень много.

> смысл?

Смысл в переносимости и надёжности. В независимости от endianess платформы и от её отношения к невыровненному доступу.

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

> ты гарантировано наживаешь проблемы при другом endianess.

#ifdef/#endif кто-то отменял?

кроме того, при ручном формировании ты также заведомо используешь привязку к конкретному endian
либо используешь все те же #ifdef/#endif и макросы для установки значений полей

смысл?

rei3er
()
Ответ на: комментарий от anonymous

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

откуда сведения?

> В независимости от endianess платформы и от её отношения к 
> невыровненному доступу.

читай пост выше

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

> #ifdef/#endif кто-то отменял?

Да ты неумён весьма.

Тебе придётся тогда писать два варианта - один с ручной упаковкой, и второй с идиотскими структурками. И на кой? Лучше оставить только с ручной упаковкой.

> кроме того, при ручном формировании ты также заведомо используешь привязку к конкретному endian

Чушь какая. Болеешь, бедненький?

push_ui32(буффер, чаво-то); и оно тебе его отформатирует в нужной последовательности.

> и макросы для установки значений полей

Никаких тебе "полей". Забудь про структуры навсегда.

anonymous
()
Ответ на: комментарий от rei3er

> откуда сведения?

Из анализа твоих высказываний. Мне и меньшего хватает чтоб оценить уровень подготовки программиста, полезное для собеседований умение.

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

>> боюсь, один останешься

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

Чего тут бояться? Таких CS-ушибленных начальников, как ты, не очень много. Посмотри на любые исходники линуксовых драйверов - там куча hw-related структур.

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

> Да ты неумён весьма.

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

> Чушь какая. Болеешь, бедненький?

здоров, спасибо за заботу

> push_ui32(буффер, чаво-то); и оно тебе его отформатирует в нужной 
> последовательности.

ну есть, допустим, следующая структура (из того же драйвера NIC)

/* TPD definition */
typedef struct _TpdDescr {
    uint64_t        addr;
    uint16_t        buf_len :14;
    uint16_t        dma_int :1;
    uint16_t        tx_int  :1;
    uint16_t        vlan;
    uint16_t        eop     :1;
    uint16_t        ipver   :1;     // 0 : IPV4, 1:IPV6
    uint16_t        ins_vlan:1;
    uint16_t        my_xsum :1;
    uint16_t        segment :1;
    uint16_t        ipxsum  :1;
    uint16_t        tcpxsum :1;
    uint16_t        udpxsum :1;
    uint16_t        vlan_tag:1;
    uint16_t        eth_type:1;
    uint16_t        iphdrlen:4;
    uint16_t        tcphdrlen:4;
    uint16_t        hdr_flag:1;
    uint16_t        tcp_mss :13;
} _AT_ATTRIB_PACK_ TpdDescr;

как ты с ней будешь работать? это будет удобно? эффективно? (учитывая, что работа с битовыми полями может быть оптимизирована компилятором)

> Никаких тебе "полей". Забудь про структуры навсегда.

скажи это разработчикам драйверов, ты ведь умный, они тебя послушаются

rei3er
()
Ответ на: комментарий от anonymous

> Из анализа твоих высказываний. Мне и меньшего хватает чтоб оценить 
> уровень подготовки программиста, полезное для собеседований умение.

вам до моего уровня еше расти и расти

вы не тролль случайно?

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

> вам до моего уровня еше расти и расти

+1.

anonymous
()
Ответ на: комментарий от tailgunner

> Посмотри на любые исходники линуксовых драйверов - там куча hw-related структур.

А теперь посмотри на проблемы, с которыми это угрёбистое пионерское говнецо портируется на другие платформы.

Я сам где-то лет восемь назад портировал Reiserfs на sparc, намучался тогда с быдлокодом на всю оставшуюся жизнь.

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

>> Посмотри на любые исходники линуксовых драйверов - там куча hw-related структур.

> А теперь посмотри на проблемы, с которыми это угрёбистое пионерское говнецо

Ты точно один останешься, если всех "угребистых пионеров" убьешь

> портируется на другие платформы

Без особых проблем.

> Я сам где-то лет восемь назад портировал Reiserfs на sparc

Ну и причем ФС к драйверам?

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

> Когда ты сам ручками пакуешь и распакуешь, ты можешь правильно учесть и endianess и выравнивания данных и размер типов. Запихав всё в структуру, ты гарантировано наживаешь проблемы при другом endianess.

хорошо, анонимус - обычный ламер, с него взятки гладки. но вам то разве не очевидно, что htonX/ntohX* в случае с сетевыми пакетами или аналог при работе, скажем, с локальным железом никто не отменял :-? IMHO это очевиднейшая вещь.

не верю, что участники дискуссии её не понимают. до той степени, что рассматриваю как провокацию флейма причём на ровном месте. есть желание пофлеймить - не проблема. но давайте хоть тему выберем поприличнее.

*) да, в случае передачи в структуре полей в формате с плавающей точкой то-же есть правила конвертации. не такие очевидные, как штатные htons но тем не менее. есть к примеру в описании XDR.

// wbr

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

> хорошо, анонимус - обычный ламер, с него взятки гладки. но вам то разве не очевидно, что htonX/ntohX* в случае с сетевыми пакетами или аналог при работе, скажем, с локальным железом никто не отменял :-? IMHO это очевиднейшая вещь.

Может я чего-то не понимаю, но какое отношение эти функции имеют к передаче упакованной структуры? Вернее так, если их применять для этой цели, то в чём тогда смысл создавать именно упакованную структуру для передачи данных по сети?

Как я понял, весь сыр бор разгорелся, когда дошли до работы в Си с упакованными структурами.

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

> для этой цели, то в чём тогда смысл создавать именно упакованную 
> структуру для передачи данных по сети?

_формат_ заголовков (специфицированный до разряда) и удобство работы
посмотрите 

linux/ip.h
linux/tcp.h
net/ethernet.h
...

гораздо более логично один раз описАть все структуры данных (с учетом endianess хоста и выравнивания) и потом ими пользоваться, нежели каждый раз их формировать

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

> Может я чего-то не понимаю, но какое отношение эти функции имеют к
передаче упакованной структуры? Вернее так, если их применять для этой
цели, то в чём тогда смысл создавать именно упакованную структуру для
передачи данных по сети?

возьмём любой бинарный by design протокол - ARP/RARP, IPv4/6, ICMP,
UDP, TCP, GRE, PPTP/PPP & K - you name бо имя им легион. протокол
пакетный и, используя C, вполне логично описывать пакеты, передаваемые
по сети, в виде структур и принимать/передавать их в приложении
соответственно. с учётом того, что локальный порядок байт может
[но не обязан] отличаться от сетевого, htonX/ntohX служат для
конвертации полей структуры.

#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);

ps: да, я понимаю, что я сейчас говорю прописные и банальные вещи,
которые по-идее должны быть очевидны любому, кто хотя бы раз занимался
разработкой под *NIX системы. да и не только - тот же WSA на этом
уровне работает совершенно аналогично.

> Как я понял, весь сыр бор разгорелся, когда дошли до работы в Си
с упакованными структурами.

ну весь сыр-бор разгорелся на фоне расширений компилятора C и GCC
как конкретный пример и одно из его расширений - attribute(packed).
иногда оно необходимо, в большинстве случаев конечно же нет.

// wbr

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


ps: пример с бинарными сетевыми протоколами - это отнюдь не повод к holy war. всего лишь констатация очевидного факта, что они уже есть, они уже чрезвычайно распространены и, если задача требует того, с ними нужно как-то эффективно работать. это IMHO отнюдь не повод для достаточно бесперспективной дискуссии "а вот если бы они были текстовыми".

// wbr

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

===
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);
===

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

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

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