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
, и ни одна из них не дает мне повторяющуюся ошибку символа .
ИЗМЕНИТЬ:
Я думаю, что компилятор сломан:
Я удалил все из шапки, а также исходные файлы. Теперь 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#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];
// ...
}
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
составные литералы могут или не могут быть константными выражениями (Инициализировать статическую переменную элементом составного константного литерала), поэтому может или может не использоваться в качестве инициализатора для static
переменных.
Вариант 2: изменение макроса на массив static const
. Плюсы: не нужно C99
. Минусы: НЕ МОЖЕТ инициализировать переменную static
. Компилятор кажется сломанным и не позволяет мне это сделать.
Вариант 3: Магические числа. Плюсы: Не нужно C99
. Может инициализировать переменную static
. Минусы: магические числа.
Вариант 4: Много макросов (на каждый из массивов, ведь не только на этот!). Плюсы: Не нужно C99
. Минусы: Загрязнение глобального пространства имен.
extern
для ссылки на эту переменную. Однако, поскольку переменнаяstatic
, она не должна быть известна нигде, кроме файла, в котором она объявлена. (поэтому переменная будет помечена как «статическая» - person user3629249   schedule 07.02.2019C99
(хотя у него есть неполный<stdint.h>
), так что единственный способ, которым я нашел для выполнения, что есть хотьstatic const
массивы. Однако кажется, что компилятор даже не позволит мне это сделать. Единственным оставшимся вариантом было бы иметь много макросов (нежелательно) или магические числа с комментариями. - person alx   schedule 07.02.2019static const
s, но не знал, почему, но вчера я нашел очень и очень вескую причину:static const
s нельзя использовать для инициализацииstatic
переменных. - person alx   schedule 07.02.2019xc8
тьфу, были только с этим проблемы. Какой смысл вREG_OSCCON_IRCF_FREQ_16_MHZ
? Разве это не может быть просто#define REG_OSCCON_IRCF_FREQ_16_MHZ 16000000u
? Я помню, что уxc8
есть проблемы с вычислением целочисленных констант, я бы посоветовал добавить суффикс сull
. Но я должен сказать это: найдите мусорное ведро, положите туда pic18, купите более дешевый stm32 и перейдите на gcc. Вы используете бесплатную версию xc8? Вы можете сделатьREG_OSCCON_IRCF_FREQ
просто статическим массивом, что на самом деле сэкономит больше памяти. На приличном компиляторе. С оптимизатором. - person KamilCuk   schedule 08.02.2019REG_OSCCON_IRCF_FREQ_16_MHZ
: этот макрос - это значение, которое мне нужно записать в полеIRCF
регистраOSCCON
для изменения на частоту sysclk 16 МГц, и, следовательно, строкуreg_OSCCON_IRCF_set(REG_OSCCON_IRCF_FREQ_16_MHZ);
После этого я изменяю переменнуюsys_freq
, которая является переменной, которую я создал запомнить, какова текущая частота clk. - person alx   schedule 08.02.2019ULL
? Во-первых, этоC99
, поэтому я не уверен, что компилятор его поймет, а во-вторых, константный интеграл гарантированно не переполнится, не так ли? И в-третьих, это дерьмо не принимает дажеuint_least64_t
, поэтому я не думаю, что оно приметunsigned long long
. Хотел бы я, чтобы здесь был GCC, или, по крайней мере, SDCC был достаточно стабилен, чтобы его использовать. - person alx   schedule 08.02.2019static
(я думаю, такжеconst
) вы говорите о варианте 2 выше? Это не позволило бы мне инициализироватьstatic
variables. Кроме того,const
составным литералам, которые одинаковы, разрешено совместно использовать память, поэтому, в конце концов, они должны использовать одну и ту же память (с приличным компилятором, которого нет в XC8) - person alx   schedule 08.02.2019