我正在嘗試類似通用的代碼,并且我有一個這樣的函式(洗掉了很??多不相關的代碼):
typedef uint8_t (*struct_converter_t)(void *, char *);
void convert_struct(
struct_converter_t converter, // this is a function
const char * file_name
){
some_struct_t * some_struct;
converter(some_struct, some_string_buffer);
}
當我嘗試分配一個需要some_struct_t(不是void *)的函式時:
static uint8_t some_converter(some_struct_t * vd, char * s);
像我struct_converter_t這樣:
struct_converter_t converter = some_converter; // WARNING HERE
我得到這個:
從不兼容的指標型別 'uint8_t (*)(some_struct_t *, char *)' {aka 'unsigned char (*)(struct <匿名> *, char *)'} [-Wincompatible-pointer-types]
我在 C 方面沒有經驗,我想知道是否有辦法優雅地擺脫這個警告。
uj5u.com熱心網友回復:
您分配給函式指標型別的函式具有與函式指標不兼容的引數。
您的函式將 asome_struct_t *作為第一個引數,但函式指標型別將 avoid *作為第一個引數。雖然任何物件指標都可以轉換為 a 或從 a 轉換void *,但這不會擴展到函式指標引數。
您需要更改函式以void *使其第一個引數與函式指標兼容。然后在函式內部,您可以將該void *引數轉換為some_struct_t *.
uj5u.com熱心網友回復:
在 C 中,您可以將型別引數提供X*給需要void*. 但這就是轉換的結果。您不能將第一個引數X*為 a 的函式用作引數的引數,該引數是第一個引數為 a 的函式void*。
原因是 C 不保證這一點X*并且void*具有相同的表示。它確實保證編譯器知道如何以不破壞資訊的方式將 a 轉換X*為 a void*,以便以后可以將其轉換回X*. 但void*可能看起來完全不同。
因此編譯器可以插入將 更改X*為void*. 但是它如何將 a char*(*)(X*)(引數為 an 的函式X*)更改為 a char*(*)(void*)?如果函式期望的arg型別為char*(*)(void*), then it will mostly likely call arg(v) wherev has typevoid* . What then happens if arg actually expects anX*`?
為了讓編譯器允許這種可能性,它必須以某種方式包裹arg在通常稱為蹦床的東西中。一個接受 anX*并將其轉換為 avoid*以呼叫不同函式的函式。這并不容易——一方面,它必須將蹦床存盤在某個地方——因此 C 拒絕將其作為自動轉換來執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437874.html
下一篇:可以用不同的約束子型別實體化
