符号“ file @ variable”多次定义

时间:2019-02-06 16:54:57

标签: c header-files mplab xc8

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变量(我将仅针对staticconstextern const进行测试)进行操作,但是还有enumstatic 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,我没有。 EDIT const复合文字可能可能不是常量表达式(Initialize static variable with element of const compound literal),因此可能可能不能用作static变量的初始化程序。

选项2:将宏更改为static const数组。 优点:不需要C99。 缺点:无法初始化static变量。编译器似乎坏了, 不允许我这样做。

选项3:魔术数字。 优点:不需要C99。可以初始化一个 static变量。 缺点:魔术数字。

选项4:很多宏(对于每个数组,因为它不仅 这个!)。 优点:不需要C99。 缺点:污染全局名称空间。

1 个答案:

答案 0 :(得分:0)

肯定XC8编译器已损坏。

今天,使用static inline函数时出现了类似的错误。我已经用谷歌搜索了,看来编译器对这种代码不是很好。