簡體   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