繁体   English   中英

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

[英]invalid conversion from 'long int' to 'void (*)()' [-fpermissive]

嗨,我正在为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;

为什么??

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

编译器将0xF000识别为int并放弃将此值分配给指针。 您应该显式转换它:

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

我从AVRFreak论坛获得的答案,

使用TYPEDEF

typedef void (*fptr_t)(void);

fptr_t boot_start = (fptr_t)0xF000;

...
  boot_start();

否则得到警告的原因是0xF000对于AVR是long int。 '='左边的东西是一个指向函数的指针。 因此,您正在尝试为指针分配一个整数。 C认为这可能是一个错误(通常是一个错误!),因此警告您。 您平息该警告的方式是说:“此0xF000数字确实不是指针值”。 您的方式是使用类型转换。 现在,您可以使用(等待)进行此操作:

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

但是正如您所看到的,在等式的两边几乎都有完全相同的(相当复杂的)结构。 因此,将所有细节放入一个单独的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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM