LINUX.ORG.RU

быдлокодер хочет замаскировать свой говнокод от ругательств компилятора?

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

Он хочет спрятать их от заказчика, иначе не получит свои 5$.

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

быдлокодер хочет замаскировать

Виталик, это ты? ;)

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

JackYF, спасибо. Всё то, что нужно.

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

хм-хм ... пробую: #pragma GCC diagnostic ignored "-Wall", компилируется без ошибок,

а когда пробую #pragma GCC diagnostic ignored "-Wno-attributes"
то выдается:
common.h:10:9: предупреждение: unknown option after «#pragma GCC diagnostic» kind [-Wpragmas]

Почему так?

pacify ★★★★★
() автор топика

Всё, разобрался. Игнорировать надо не no-attributes, а просто «attributes».

Поэтому, писать так:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
typedef struct {
uint8_t Type PACKED;
} Packet;
#pragma GCC diagnostic pop

pacify ★★★★★
() автор топика

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

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

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

Вообще-то бывают иногда. Может быть не в Си, но в других языках я встречал неуместные варнинги.

unC0Rr ★★★★★
()

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

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

Все-таки, все должно компилироваться с -Wall -Werror, иначе это — точно говнокод.

скажи мне, почему для поля uint8_t нельзя указать __attribute__ ((packed)) ? а для других типов (>1 байта) - можно? выдается варнинг

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

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

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

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

Будешь ты думать, что структура упакована, а на самом деле — хрен!

компилятор gcc >= 4.6 понимает ((packed))

pacify ★★★★★
() автор топика

Короче,

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

typedef struct {
uint8_t Type __attribute__ ((packed));
} Packet;

int main() {
return 0;
}

$ gcc-4.6 test.c
test.c:4:3: предупреждение: атрибут «packed» для поля типа «uint8_t» проигнорирован [-Wattributes]

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify
pacman -Q gcc-multilib 
gcc-multilib 4.7.2-1

cat 1.c
#include <stdio.h>
#include <stdint.h>

typedef struct{
	int i;
	uint8_t ch1;
	int j;
	uint8_t ch2;
} pchar __attribute__ ((packed)) ;

typedef struct{
	short int i;
	short int k;
	short int j;
	short int l;
	short int m;
} pint __attribute__ ((packed)) ;

typedef union{
	pchar P;
	pint I;
	char ch[10];
} pbytes;

int main(int argc, char **argv){
	pchar pack;
	printf("pack sz = %d\n", sizeof(pack));
}

gcc 1.c 
1.c:9:1: предупреждение: атрибут <<packed>> проигнорирован [-Wattributes]
1.c:17:1: предупреждение: атрибут <<packed>> проигнорирован [-Wattributes]
Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от pacify

Нашел:

-Wpacked Warn if a structure is given the packed attribute, but the packed attribute has no effect on the layout or size of the structure. Such structures may be misalignedfor little benefit. For instance, in this code, the variable f.x in structbar will be misaligned even though struct bar does not itself have the packed attribute

Прикол в том, что в некоторых случаях gcc сам не упаковывает структуры, если видит в этом смысл.

Блин, а ведь ни хрена он их не упаковал…

Eddy_Em ☆☆☆☆☆
()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

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

typedef struct {
uint8_t Type1 __attribute__ ((packed));
uint16_t Type2 __attribute__ ((packed));
} Packet1;

typedef struct {
uint8_t Type1;
uint16_t Type2;
} Packet2;

typedef struct {
uint8_t Type1;
uint16_t Type2;
} Packet3;

#pragma pack(1)

typedef struct {
uint8_t Type1;
uint16_t Type2;
} Packet4;

int main() {
printf(«%d\n», (int)sizeof(Packet1));
printf(«%d\n», (int)sizeof(Packet2));
printf(«%d\n», (int)sizeof(Packet3));
printf(«%d\n», (int)sizeof(Packet4));
return 0;
}

./a.out
3
4
4
3

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

Хрен-те что творится!

Вот так — работает:

cat 1.c 
#include <stdio.h>
#include <stdint.h>

typedef struct{
	int i __attribute__((packed));
	uint8_t ch1;
	int j __attribute__((packed));
	uint8_t ch2;
} pchar;

typedef union{
	pchar P;
	char ch[10];
} pbytes;

int main(int argc, char **argv){
	pbytes P;
	pchar *p = &P.P;
	p->i = 0x01020304;
	p->ch1 = 5;
	p->j = 0x05060708;
	p->ch2 = 9;
	int i;
	printf("pack sz1 = %d\n", sizeof(*p));
	for(i = 0; i < 10; i++) printf("pack.%d = %d\n", i, P.ch[i]);
	
}

gcc 1.c && ./a.out 
pack sz1 = 10
pack.0 = 4
pack.1 = 3
pack.2 = 2
pack.3 = 1
pack.4 = 5
pack.5 = 8
pack.6 = 7
pack.7 = 6
pack.8 = 5
pack.9 = 9

Eddy_Em ☆☆☆☆☆
()
Ответ на: Хрен-те что творится! от Eddy_Em

Почти дошло!

Достаточно указать packed лишь там, где может быть разрыв в упаковке:

typedef struct{
    int i __attribute__((packed));;
    uint8_t ch1;
    int j __attribute__((packed));
    uint8_t ch2;
} pchar;
Правда, непонятно, почему если убрать первый packed, в конце структуры еще добавляется 2 нуля.

Eddy_Em ☆☆☆☆☆
()
Ответ на: Почти дошло! от Eddy_Em

Достаточно указать packed лишь там, где может быть разрыв в упаковке:

Надо указывать packed для полей, которые не нужно выравнивать
по-умолчанию, по определенной границе (например, по началу каждого
4-го байта памяти). Тогда они не выравниваются, и пакуются «вплотную».

Такая же инструкция есть и в ассемблерах, например для i386 (MASM/TASM).

pacify ★★★★★
() автор топика
Ответ на: Я - идиот! от Eddy_Em

typedef <определение типа> <обозначение типа>

угу, в http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
написано что атрибуты надо указывать в определении типа:

typedef union __attribute__ ((__transparent_union__))
{
int *__ip;
union wait *__up;
} wait_status_ptr_t;

pid_t wait (wait_status_ptr_t);

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

для заказчика такой код как у меня - это вообще почти идеал.

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

Все по тому же, потому что везде такие же быдлокодеры. Ты запрещенный ролик ко дню молодежи смотрел? А фильм «Изображая жертву?» Они практически полностью посвящены такому быдлокодерству на ЭВМ и в жизни.

Стыдно.

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

Где ошибка в моём коде?

Каждое стандартное предупреждение — это потенциальная ошибка. Сегодня, завтра или через год.

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

Сегодня, завтра или через год.
... списываются неадекватные деньги, или происходят аварии на АЭС.

Да. Поэтому надо пользоваться компимлятором GCC - результатом труда
стрёмного мужика, который живёт в США, скрывается от ФБР и не имеет
сотового телефона. Продолжать сентенцию про использование линукса
в структурах Минатома я не буду, так как это подпадает под С/СС.

pacify ★★★★★
() автор топика

Мне вот интересно, какими соображениями надо руководствоваться, что б реквестировать упаковку базовых типов.

ТС, ворнинги убирать никогда-никогда не надо. Для C/C++ GCC и с all+pedantic даже не все их пихает

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

ТС, ворнинги убирать никогда-никогда не надо.

Я развлекаюсь :)

что б реквестировать упаковку базовых типов.

Трафик вряд ли это будет экономить (клиенты шлют только один запрос).
Но я хочу, чтобы использование памяти было однозначным, и не надо было думать о «дырках» в структурах.

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

то есть написать нормальный код сериализации нельзя? Нужно сделать обязательно «нестандартное» поведение?

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

А думать об оптимизации доступа к объектам кто будет? Правила выравнивания были не так просто придуманы.

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

Это и есть нормальный код сериализации + увеличение скорости за счет экономии места.

А ты как предлагаешь? По-другому никак.

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

Если к этим данным будет 1 запрос в секунду, никакой оптимизации нафиг не надо. А вот если часто — можно переделать структуру в выровненную и запихнуть общий ресурс в разделяемую память.

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

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

А вот то, что при сериализации ты пишешь платформозависимый код - очень плохо. Потом ищи концы

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

при сериализации ты пишешь платформозависимый код

Где ты видишь платформозависимый? Если использовать только строгие типы данных (вроде int8_t, int64_t и т.п.) + упаковывать данные, никакой зависимости не будет!

// а, еще надо определиться с endianness

Eddy_Em ☆☆☆☆☆
()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от pacify

у меня только linux (i386/amd64)

linux - это не только i386/amd64.

Или у тебя какой-то свой, персональный linux?

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

а вот тут anonymous, Eddy_Em и другие правы.

not all the world's a VAX — лучше подумать об этом заренее, чем отгребать потом кучю граблей.

помни так же о: programming is like sex — one mistake and you'll must support it for whole life

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

not all the world's a VAX

хорошо, подумаю об endianness заранее, никогда не заморачивался этим

опыт приходит постепенно, я много времени потратил на тупую работу в офисах

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

тут даже и думать не надо — всё что уходит в сеть обязоано пройти через hton{s,l}(3)! и всё, что из сети — через ntoh{s,l}(3). считай, что это закон. (исключение char — там можно забить)

Disclaimer: тред не читал.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)

Сами же нашли правильное решение — не указывать __attribute__((packed)) для отдельного поля, а «паковать» всю структуру:

struct __attribute__((packed)) Foo {
        uint8_t    f1;
        uint16_t   f2;
};
Тогда GCC ругаться не будет.

А ворнинги прагмами дисэйблить — это реально моветон ;)

mr_doug
()

А ругается-то он правильно совершенно. 8-битовые поля не «упакуешь» никак же. __attribute__ ((packed)) у поля изменяет именно оффсет для этого конкретного поля, и никакого эффекта для однобайтовых полей не имеет.

Так что при наблюдении вышеуказанного ворнинга, можно было бы просто убрать __attribute__ ((packed)) у однобайтовых мемберов:

 typedef struct {
-       uint8_t Type1 __attribute__ ((packed));
+       uint8_t Type1;
        uint16_t Type2 __attribute__ ((packed));
 } Packet1;

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

тут даже и думать не надо — всё что уходит в сеть обязоано пройти через hton{s,l}(3)! и всё, что из сети — через ntoh{s,l}(3)

а если я люблю гонять данные по сети в little-endian? %)

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

Откуда я буду знать порядок твоих байтов? Идёт, например, полуслово, двойное слово, байт, байт и слово. Ладно то, что все ожидают по сети байты в прямом порядке. А тут ещё и нужно знать, какие группы байтов идут, чтобы их обратно перевернуть в нормальные.

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