Символ "файл @ переменная" определен более одного раза

IDE: MPLAB X v2.15

CC: XC8 v1.32

Целевое устройство: PIC18f45k20

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

static const int aaasdf = 3;

Этот заголовок имеет правильное включение охранников в начале:

#ifndef PRJ_REG_H
#define PRJ_REG_H

И в конце:

#endif

Если у меня есть та же самая переменная в любом другом заголовочном файле, она прекрасно компилируется, но когда эта переменная находится в этом конкретном файле, она дает мне error: (845) symbol "reg@aaasdf" defined more than once

Но если я прокомментирую эту переменную, она больше не будет существовать и будет жаловаться, потому что она мне нужна в каком-то файле.c.

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

Что еще я могу сделать, чтобы отладить это?

РЕДАКТИРОВАТЬ:

Это делает для любого static const переменная, (завтра проверю только static, const или же extern const), что я создаю в этом файле, но есть и enumс и static inline функции, и ни одна из них не дает мне повторную ошибку символа.

РЕДАКТИРОВАТЬ:

Я думаю, что это компилятор, который сломан:

Я удалил все из шапки, а также исходные файлы. Теперь main - это бесконечный цикл, и все так.

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

Ни один мой заголовок не содержит никакого другого моего заголовка.

Что вызывает ошибку: любой заголовок, который включен во многие исходные файлы и содержит static const переменная любого типа. Под многими я подразумеваю, что, если я включаю заголовок только в его исходный файл и другой файл, он не вызывает ошибку, но если он включен в 2 исходных файла, которые не являются его исходным файлом, он вызывает ошибку,

РЕДАКТИРОВАТЬ:

Как и требовалось, вот MCV-пример того, что я хочу (не ошибка компиляции):

// reg.h

enum    Reg_OSCCON_IRCF_Values {
    REG_OSCCON_IRCF_FREQ_31_KHZ = 0x0u,
    REG_OSCCON_IRCF_FREQ_250_KHZ    = 0x1u,
    REG_OSCCON_IRCF_FREQ_500_KHZ    = 0x2u,
    REG_OSCCON_IRCF_FREQ_1_MHZ  = 0x3u,
    REG_OSCCON_IRCF_FREQ_2_MHZ  = 0x4u,
    REG_OSCCON_IRCF_FREQ_4_MHZ  = 0x5u,
    REG_OSCCON_IRCF_FREQ_8_MHZ  = 0x6u,
    REG_OSCCON_IRCF_FREQ_16_MHZ = 0x7u
};
#define REG_OSCCON_IRCF_FREQ        ((const uint32_t [8]){      \
                           31000u,      \
                          250000u,      \
                          500000u,      \
                         1000000u,      \
                         2000000u,      \
                         4000000u,      \
                         8000000u,      \
                        16000000u       \
                    })

static inline   void reg_field_set(volatile uint8_t *reg,
                uint8_t mask, uint8_t posn, uint8_t val)
{

    *reg    = (*reg & ~mask) | ((val << posn) & mask);
}

static inline   void reg_OSCCON_IRCF_set(uint8_t val)
{

    reg_field_set(&OSCCON, _OSCCON_IRCF_MASK, _OSCCON_IRCF_POSN, val);
}

// pwm.c

#include "reg.h"
extern uint32_t sys_freq;

int foo(/**/)
{
    static const uint32_t   freq_min =
        REG_OSCCON_IRCF_FREQ[REG_OSCCON_IRCF_FREQ_16_MHZ] /
        (UINT8_MAX * 4 *
        REG_T2CON_T2CKPS_PRESCALER[REG_T2CON_T2CKPS_PRESCALER_1]);

    reg_OSCCON_IRCF_set(REG_OSCCON_IRCF_FREQ_16_MHZ);
    sys_freq    = REG_OSCCON_IRCF_FREQ[REG_OSCCON_IRCF_FREQ_16_MHZ];
    // ...
}

Вариант 1: как показано выше, используя макрос, который расширяется до constсоставной массив литерал, где я могу получить доступ к любому из его элементов (во время компиляции или во время выполнения). Необходимость C99которого у меня нет. РЕДАКТИРОВАТЬ: const составные литералы могут быть или не быть константными выражениями ( Инициализировать статическую переменную с элементом составного литерала const), и поэтому могут быть или не быть допустимыми в качестве инициализаторов для static переменные.

Вариант 2: изменение макроса на static const массив. Плюсы: не нужны C99, Минусы: НЕ МОЖЕТ инициализировать static переменная. Компилятор кажется сломанным и не позволяет мне это делать.

Вариант 3: Магические числа. Плюсы: не нужны C99, Можно инициализироватьstatic переменная. Минусы: магические числа.

Вариант 4: много макросов (для каждого из массивов, потому что он не только этот!). Плюсы: не нужны C99, Минусы: загрязнение глобального пространства имен.

1 ответ

Решение

Определенно XC8 компилятор не работает.

Сегодня подобные ошибки появились при использовании static inline функции. Я гуглил об этом, и кажется, что компилятор не очень хорош с таким кодом.

Другие вопросы по тегам