我想將 C 中的物件轉換為另一種型別,而不轉換資料,也不需要使用指標。我知道你可以這樣做:
float a = 1.2;
int b = *(int*)(&a);
但是我希望能夠對就地構造的文字和結構進行處理(如果這是正確的術語)。例如(想象一下我可以暫時參考一個文字):
void somefunc(int i){...}
somefunc(*(int*)(&1.2))
我所說的就地構建的意思是,假設我有一個 struct vec2:
struct vec2{
float x,y;
};
我希望能夠做類似的事情
void somefunc(vec2 v){...}
somefunc(ConversionlessCast(vec2{1.f,2.f}))
這可能嗎?
編輯:我想澄清一下,我不在乎這是否安全。我只是想知道是否有辦法做到這一點。我應該澄清一下,我也不想制作暫存變數。
Edit2:我意識到這個問題在沒有示例的情況下是多么糟糕,并且在最初輸入示例時,我意識到無論如何我想要使用它的答案是什么。
我正在嘗試一種為我正在開發的 ui 系統進行樣式設定的方法,并且希望能夠使用一個函式來設定樣式屬性。我想傳遞一個字串,然后傳遞一個值,并使用該字串來確定如何解釋該值。現在很明顯我應該使用 va_args 這樣做。但是,我仍然對是否有辦法做我最初要求的事情感興趣,因為我最初的計劃是使用一個聯合型別,它包含一個屬性可能是的所有型別,比如
struct Property{
union{
u32 val_u32;
f32 val_f32;
//other possible types
};
};
然后使用前面的字串來選擇要使用的值。不幸的是,使用初始化串列只接受第一種型別,u32。所以我想想出一種方法來初始化一個屬性,比如
#define Property(x) Property{(magic that reinterprets anything as the first type on property})
Property(vec2{1.f,2.f})
uj5u.com熱心網友回復:
您可以使用復合文字中的聯合將一個物件的位元組重新解釋為另一個物件。在這段代碼中:
printf("%d\n", (union { float f; int i; }) {a} .i);
創建一個聯合,并f使用 的值初始化其成員a。然后該i成員由 訪問.i。根據 C 2018 注釋 99 到第 6.5.2.3 4 條,重新解釋具有新型別的位元組,int.
(這是針對 C 的。C 標準沒有定義其行為。)
uj5u.com熱心網友回復:
通過指標將一種型別重新解釋為另一種型別是違反嚴格別名的行為,會觸發未定義的行為,因此不安全。
做到這一點的安全方法是使用聯合:
union u {
int i;
float f;
};
union u x = { .f=1.2f };
int y = x.i;
或使用memcpy:
float a = 1.2;
int b;
memcpy(&b, &a, sizeof b);
uj5u.com熱心網友回復:
我做了一個小實驗——如果您查看 C 代碼,我撰寫了一些似乎使用指標的代碼,但如果您查看生成的匯編代碼,它不使用指標。這是我寫的:
static inline int float_to_int(float f) {
return *(int*)(&f);
}
int main(int argc, char **argv) {
printf("%d\n", float_to_int(3.0)); // prints 1077936128
}
我在編譯器生成的代碼中發現了這一點(gcc -O2 -s):
main:
... etc ...
movl $1077936128,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/487796.html
標籤:C
