从'long int'到'void(*)()的无效转换[-fpermissive]

时间:2016-02-24 08:28:12

标签: c++ pointers bootloader

您好我正在为MCU的引导加载程序编写很少的修改代码。我试图做的修改是为启动加载器供电,即使看门狗定时器复位也是如此。

我正在使用此函数原型来定义引导加载程序的地址,我收到错误:

  

从'long int'到'void(*)()'[-fpermissive]

的无效转换

我的代码是

#if defined ( __AVR_ATmega1284P__ )
    void (*boot_start)(void) = 0xF000;
#elif defined ( __AVR_ATmega2560__ ) 
    void (*boot_start)(void) = 0x1F000;
#endif

0xF000和0x1F000是存储空间。如果我的代码是“

,我不会收到此错误
void (*boot_start)(void) = 0x0000;

为什么??

3 个答案:

答案 0 :(得分:3)

0x0000只是NULL的另一个名称,它将作为指针值编译好,但其他值需要显式转换为正确的类型。

答案 1 :(得分:1)

编译器将0xF000识别为int并丢弃将此值指定给指针。你应该明确地施展它:

void (*boot_start)(void) = (void (*)())0xF000;

答案 2 :(得分:0)

我从AVRFreak论坛得到的答案,

使用TYPEDEF,

typedef void (*fptr_t)(void);

fptr_t boot_start = (fptr_t)0xF000;

...
  boot_start();

你得到警告的原因是0xF000是AVR的长整数。 '='左边的东西是指向函数的指针。所以你试图为指针分配一个整数。 C认为这可能是一个错误(通常是!)所以它会警告你。你平息该警告的方式是说“没有这个0xF000号码确实是一个指针值”。你这样做的方式是使用类型转换。现在你可以用(等待它)来做到这一点:

void (*boot_start)(void) = (void(*)(void))0xF000;

但是你可以看到,在equals的两边几乎完全相同(相当复杂)的结构。因此,将所有细节放入一个typedef并在多个位置使用它是有意义的。

如果函数类型更复杂,甚至可能是这样的:

int (*boot_start)(char, long, int *) = (int (*)(char, long, int *))0xF000;

这确实看起来确实非常愚蠢 - 不仅是你很有可能犯了输入错误而且只是试图记住这里的语法是一个真正的痛苦!因此,您只需使用typedef定义一次函数接口:

typedef int (*myfn_t)(char, long, int *);

myfn_t boot_start  = (myfn_t))0xF000;

并且更易于输入和管理。如果稍后在函数中添加第四个char **参数,现在只在一个地方执行 - typedef。

感谢C Lawson和Yuriy。