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
.Минусы: загрязнение глобального пространства имен.