符号 "file@variable" 定义了不止一次
Symbol "file@variable" defined more than once
IDE:MPLAB X v2.15
抄送:XC8 v1.32
目标器件:PIC18f45k20
我有一个 header 文件 reg.h
,其中包含一个变量
static const int aaasdf = 3;
header开头有适当的包含守卫:
#ifndef PRJ_REG_H
#define PRJ_REG_H
最后:
#endif
如果我在任何其他 header 文件上有相同的变量,它可以正常编译,但是当该变量在这个特定文件中时,它会给我 error: (845) symbol "reg@aaasdf" defined more than once
但是如果我评论那个变量,它就不再存在了,它会抱怨,因为我需要它在一些 .c 文件中。
这个奇怪的名字只是为了测试,以确保没有任何其他同名变量。
我还能做些什么来调试它?
编辑:
它对我在该文件中创建的任何 static const
变量执行此操作(明天我将仅测试 static
、const
或 extern const
) ,但也有 enum
和 static inline
函数,其中 none 给了我重复的符号错误。
编辑:
我认为是编译器出了问题:
我删除了 header 中的所有内容以及源文件。现在main是一个无限循环,一切都是这样。
header 是空的,但对于触发错误的变量。
我的 header 不包括我的任何其他 header。
是什么触发了错误:
许多源文件中包含的任何 header,并且包含任何类型的 static const
变量。我的意思是,如果我只在其源文件和另一个文件中包含 header,它不会触发错误,但如果它包含在 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
复合文字可以或不可以是常量表达式(),因此 可能 或 可能不 作为 static
变量的初始值设定项有效。
选项 2:将宏更改为 static const
数组。
优点:不需要 C99
。
缺点:无法初始化 static
变量。编译器似乎坏了
不允许我这样做。
选项 3:幻数。
优点:不需要 C99
。可以初始化一个
static
变量。
缺点:魔术数字。
选项 4:很多宏(对于每个数组,因为它不仅
这个!)。
优点:不需要 C99
。
缺点:污染全局命名空间。
肯定是 XC8
编译器坏了。
今天在使用static inline
函数时出现了类似的错误。我用谷歌搜索了一下,编译器似乎不太适合那种代码。
IDE:MPLAB X v2.15
抄送:XC8 v1.32
目标器件:PIC18f45k20
我有一个 header 文件 reg.h
,其中包含一个变量
static const int aaasdf = 3;
header开头有适当的包含守卫:
#ifndef PRJ_REG_H
#define PRJ_REG_H
最后:
#endif
如果我在任何其他 header 文件上有相同的变量,它可以正常编译,但是当该变量在这个特定文件中时,它会给我 error: (845) symbol "reg@aaasdf" defined more than once
但是如果我评论那个变量,它就不再存在了,它会抱怨,因为我需要它在一些 .c 文件中。
这个奇怪的名字只是为了测试,以确保没有任何其他同名变量。
我还能做些什么来调试它?
编辑:
它对我在该文件中创建的任何 static const
变量执行此操作(明天我将仅测试 static
、const
或 extern const
) ,但也有 enum
和 static inline
函数,其中 none 给了我重复的符号错误。
编辑:
我认为是编译器出了问题:
我删除了 header 中的所有内容以及源文件。现在main是一个无限循环,一切都是这样。
header 是空的,但对于触发错误的变量。
我的 header 不包括我的任何其他 header。
是什么触发了错误:
许多源文件中包含的任何 header,并且包含任何类型的 static const
变量。我的意思是,如果我只在其源文件和另一个文件中包含 header,它不会触发错误,但如果它包含在 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
复合文字可以或不可以是常量表达式(static
变量的初始值设定项有效。
选项 2:将宏更改为 static const
数组。
优点:不需要 C99
。
缺点:无法初始化 static
变量。编译器似乎坏了
不允许我这样做。
选项 3:幻数。
优点:不需要 C99
。可以初始化一个
static
变量。
缺点:魔术数字。
选项 4:很多宏(对于每个数组,因为它不仅
这个!)。
优点:不需要 C99
。
缺点:污染全局命名空间。
肯定是 XC8
编译器坏了。
今天在使用static inline
函数时出现了类似的错误。我用谷歌搜索了一下,编译器似乎不太适合那种代码。