Символ "файл @ переменная" определен более одного раза - PullRequest
0 голосов
/ 06 февраля 2019

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 s и static inline, и ни одна из них не выдает мне повторяющуюся ошибку символа.

EDIT:

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

Я удалил все из шапки, а также из исходных файлов.Теперь 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, которого у меня нет. EDIT : const составные литералы может или может не быть константными выражениями ( Инициализировать статическую переменную с элементом составного литерала const ),и поэтому может или не может быть допустимым в качестве инициализаторов для static переменных.

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

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

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

1 Ответ

0 голосов
/ 13 февраля 2019

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

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

...