Цитата(Димон Безпарольный @ Dec 6 2016, 17:51)

Обявляются в заголовочном файле:
Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */
Это не объявление, а определение. И делать определения в заголовочном файле -- плохая практика.
В C/C++ применяется так наз. раздельная компиляция. Если нужна глобальная переменная доступная во всех единицах трансляции (т. е. c-файлах) то, нужно делать так:
1. В одном заголовочном файле должно быть ОБЪЯВЛЕНИЕ:
-------decl.h--------
Код
...
extern struct BME280_t BME280_cfg;
extern struct BME280_t *p_BME280; /**< pointer to BME280 */
2. Только в одном C-файле должно быть ОПРЕДЕЛЕНИЕ:
-------def.c--------
Код
...
struct BME280_t BME280_cfg;
struct BME280_t *p_BME280; /**< pointer to BME280 */
3. Затем в др. C-файлах можно использовать эти глобальные переменные:
-------a.c--------
Код
#include "decl.h"
void f()
{
BME280_cfg.member1 = 1234;
p_BME280->member2 = 43444;
}
-------b.c--------
Код
#include "decl.h"
void g()
{
BME280_cfg.member1 = 5678;
p_BME280->member2 = 44343;
}
Любой из этих C-файлов: def.c, a.c, b.c может содержать функцию main() (и сам файл может называться main.c)
---------------------------------------------------------------------
Если переменная определена как static в каком-нибудь C-файле, то она будет доступна только в этом c-файле. Если в других C-файлах есть такое же static-определение, то это будет уже др. переменная
-------decl.h-------- Как уже было сказано -- определения в заголовочном файле -- плохо, тем не менее
Код
...
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */
-------a.c--------
Код
#include "decl.h"
void f()
{
BME280_cfg.member1 = 1234;
p_BME280->member2 = 43444;
}
-------b.c--------
Код
#include "decl.h"
void g()
{
BME280_cfg.member1 = 5678;
p_BME280->member2 = 44343;
}
После препроцессинга (в том числе обработки include-ов) перед компиляцией из a.c получится единица трансляции:
-------a.c*--------
Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */
void f()
{
BME280_cfg.member1 = 1234;
p_BME280->member2 = 43444;
}
Из b.c получится:
-------b.c*--------
Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */
void g()
{
BME280_cfg.member1 = 5678;
p_BME280->member2 = 44343;
}
Таким образом, в каждой единице трансляции будет свой комплект переменных BME280_cfg и p_BME280. При изменении переменной BME280_cfg в a.c, это никак не затронет переменную с этим же названием в b.c, ибо там своя отдельная переменная в b.c.
-----------------------------------------------
Если сделать так
-------decl.h-------- Как уже было сказано -- определения в заголовочном файле -- плохо, тем не менее
Код
...
struct BME280_t BME280_cfg;
struct BME280_t *p_BME280; /**< pointer to BME280 */
-------a.c--------
Код
#include "decl.h"
void f()
{
BME280_cfg.member1 = 1234;
p_BME280->member2 = 43444;
}
-------b.c--------
Код
#include "decl.h"
void g()
{
BME280_cfg.member1 = 5678; // *
p_BME280->member2 = 44343;
}
то программа пройдет компиляцию, но не пройдет компоновку (linkage), ибо теперь одновременно в двух единицах трансляции получаются одинаковые переменные, но при этом которые должны быть доступны для компоновки с др. единицами трансляции. Т. е. возникает неопределенность, какую например из переменных BME280_cfg использовать при записи в member1 в b.c (*): ту которая определена в a.c или ту которая в b.c...
Сообщение отредактировал conan - Dec 7 2016, 22:52