簡體   English   中英

嵌套的static_cast和const_cast

[英]Nested static_cast and const_cast

我有一個類似下面的系統調用:

int transfer(int handle, int direction, unsigned char *data, int length);

我寫了以下兩個函數:

int input(int handle, void* data, int length)
{
    return transfer(handle, 1, static_cast<unsigned char*>(data), length);
}

int output(int handle, const void* data, int length)
{
    return transfer(handle, 0, static_cast<unsigned char*>(const_cast<void*>(data)), length);
}

我不喜歡static_cast嵌套的const_cast ,有沒有辦法在一步中執行從const void*unsigned char*的轉換?

使用C樣式轉換將生成相同的程序集。 如編譯器資源管理器中所示

//Source #1
int transfer(int handle, int direction, unsigned char *data, int length);
int input(int handle, void* data, int length)
{
    return transfer(handle, 1, static_cast<unsigned char*>(data), length);
}

int output(int handle, const void* data, int length)
{
    return transfer(handle, 0, static_cast<unsigned char*>(const_cast<void*>(data)), length);
}

//Source #2
int transfer(int handle, int direction, unsigned char *data, int length);
int input(int handle, void* data, int length)
{
    return transfer(handle, 1, (unsigned char*)data, length);
}

int output(int handle, const void* data, int length)
{
    return transfer(handle, 0, (unsigned char*)data, length);
}

//Assembly (both)
input(int, void*, int):
        mov     ecx, edx
        mov     rdx, rsi
        mov     esi, 1
        jmp     transfer(int, int, unsigned char*, int)
output(int, void const*, int):
        mov     ecx, edx
        mov     rdx, rsi
        xor     esi, esi
        jmp     transfer(int, int, unsigned char*, int)

所以很明顯,簡單地使用C風格的演員表可以解決你的問題。

但是,您不應該使用C風格的演員表

C ++演員的冗長的原因是為了確保你不犯錯誤。 當維護者看到你的代碼時,重要的是他們看到const_caststatic_cast ,因為以這種方式編寫代碼告訴讀者丟棄指針的const -ness是有意和期望的行為。 代碼維護者應該看到這些強制轉換,並假設代碼背后有意圖,而不必猜測你是否知道直接從const void*unsigned char*會涉及冒未定義行為的風險。 您的示例可能不包含UB(因為您指定transfer合同是在direction為0時將data視為只讀),但重要的是,需要對代碼進行更改的任何其他人都能理解編碼實踐的深思熟慮。

您不希望data是非常量的。 如果transfer試圖修改它怎么辦? 擁有本地副本會更安全:

#include <cstring>
int output(int handle, const void* data, int length)
{
    unsigned char localData[length];
    std::memcpy(localData, data, length);
    return transfer(handle, 0, localData, length);
}

編輯:閱讀評論,這是Shlublu建議的......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM