LINUX.ORG.RU

Extern, volatile и typedef как правильно готовить?

 , ,


0

1

Имеем код

foo.h:

typedef struct {
int X1:1;
int X2:2;
int X3:3;   
}XXX_X;

extern volatile struct XXX_X ABC;

foo.c:

include "foo.h"
volatile struct XXX_X ABC;
void func(void)
{
  ABC.X1 = 1;// вот тут выскакивает ошибка "invalid use of undefined type 'volatile struct XXX_X'", ругается на точку 
}

В связи с этим вопросы

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

ЗЫ компилятор GCC, но до меня юзали кейл



Последнее исправление: nikitalol (всего исправлений: 4)

Как минимум, у тебя struct в typedef и в его использовании.

Может так:

extern volatile XXX_X ABC;
monk ★★★★★
()

Попробовать

typedef struct XXX_X{
int X1:1;
int X2:2;
int X3:3;   
} XXX_X;

но не факт что поможет и не будет новых ошибок.

BadUser
()
  • в структуре объявлены битовые поля. объяснялка здесь

ABC.X1 = 2 - никак, X1 однобитовое поле, получишь overflow in conversion from ‘int’ to ‘volatile signed char:1’ при включенном -Woverflow

  • extern volatile struct XXX_X ABC; - без struct, ты уже структуру затайпдефил

  • func()??? видимо имелось в виду void func(void)

крч тщатильнее надо

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

Когда и зачем такое обычно применяют

такое какое?

  • typedef - облегчение объявлений сложных типов, сокращение имен типов данных для улучшения читабельности и писабельности, для облегчения модификации кода при возможных изменениях .

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

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

olelookoe ★★★
()

Как это пофиксить, не меняя самого кода, а чисто за счёт опций линковщика икомпилятора тк код не мой?

как не меняя содержимого матерных частушек сделать стишки для детского утренника, но только без мата, чисто за счет навыков декламации?

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

Замечательный коментарий, спасибо, повеселил :)

func() - warning: return type defaults to ‘int’ [-Wimplicit-int]. Но всего лишь warning. Кто такой кейл не знаю, но ощущение, что староват и многое прощал.

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

Кто такой кейл не знаю, но ощущение, что староват и многое прощал.

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

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

выбрасываем struct, т.е.

extern volatile struct XXX_X ABC;

меняем на extern volatile XXX_X ABC;

и volatile struct XXX_X ABC;

на volatile XXX_X ABC;

почему? потому что тип XXX_X уже определен, через тайпдеф

olelookoe ★★★
()

Еще знаковое битовое поле размером 1 - это не гут.

vromanov ★★★
()

Как это пофиксить, не меняя самого кода, а чисто за счёт опций линковщика икомпилятора тк код не мой?

Не делай так. Никогда.

Внеси изменения в код и убедись в отсутствии сообщений об ошибках и предупреждений компилятора. Желательно использовать опции -Wall -Werror.

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

епрст

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

крч слово «struct» снеси везде кроме тайпдефа и будет тебе счастье

тип с которым ты работаешь уже имеет имя XXX_X

хз как еще объяснить, у меня уже пальцы кончились.

а, да. обрати внимание на Extern, volatile и typedef как правильно готовить? (комментарий)

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

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

Там (в кейле) компилятор либо слишком молчаливый, либо слишком много выплевывает. Например, я собирал код компилятором 5-ой версии и в гуе выставил флаг All warnings – варнинги давал только на очевидные вещи, потом поставил 6-ой компилятор, выбрав сборку с All warnings, и он начал сыпать варнинги абсолютно на все, даже на такое:

GPIO_NAME_GPIO_Port->ODR &= ~PIN_NAME_Pin; // warning: implicit conversion int to unsigned int

Хотя PIN_NAME_Pin это если углубиться #define GPIO_PIN_0 ((uint16_t)0x0001U), а GPIO_NAME_GPIO_Port #define GPIO_NAME_GPIO_Port GPIOA и ODR там объявлен как uint32_t. Хотя может я реально чего-то не понимаю.

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

что тут скажешь. увы, Гораций, в мире много кой-чего, что нашей философии не снилось (с)

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

Особенно когда код не твой Хотяяяя Кто этим ещё кроме меня будет заниматься?

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

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

Если говорить за Си, а не С++, то нормальное использование typedef - только когда необходимо скрыть поля для пользователя через opaque pointer. Во всех остальных случаях typedef struct - это признак очень плохопахнущего кода, когда перемешаны объявления типов структур и primitive типов.

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

считаешь это основной проблемой кода ТС?

Даже не буду пытаться перечислить, что там не так, начиная от знаковых битовых поле шириной в один бит и переопределением внешней (в .h) переменной локальной в модуле (.с) с таким же именем.

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