从 'long int' 到 'void (*)()' 的无效转换 [-fpermissive]
invalid conversion from 'long int' to 'void (*)()' [-fpermissive]
您好,我正在为 MCU 的引导加载程序编写一些修改后的代码。我试图做的修改是为引导加载程序供电,即使是看门狗定时器重置。
我正在使用此函数原型来定义引导加载程序的地址,但出现错误:
invalid conversion from 'long int' to '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 的另一个名称,可以编译为指针值,但其他值需要显式转换为正确的类型。
编译器将 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 的长整数。 “=”左边的东西是一个指向函数的指针。所以你试图将一个整数分配给一个指针。 C 认为这可能是一个错误(通常是!)所以它会警告您。平息该警告的方法是说 "no this 0xF000 number really is a pointer value"。你这样做的方法是使用类型转换。现在你可以用(等待它)来做到这一点:
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。
您好,我正在为 MCU 的引导加载程序编写一些修改后的代码。我试图做的修改是为引导加载程序供电,即使是看门狗定时器重置。
我正在使用此函数原型来定义引导加载程序的地址,但出现错误:
invalid conversion from 'long int' to '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 的另一个名称,可以编译为指针值,但其他值需要显式转换为正确的类型。
编译器将 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 的长整数。 “=”左边的东西是一个指向函数的指针。所以你试图将一个整数分配给一个指针。 C 认为这可能是一个错误(通常是!)所以它会警告您。平息该警告的方法是说 "no this 0xF000 number really is a pointer value"。你这样做的方法是使用类型转换。现在你可以用(等待它)来做到这一点:
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。