嵌套的static_cast和const_cast

时间:2018-07-09 15:30:59

标签: c++ static-cast 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);
}

我不喜欢const_cast中嵌套的static_cast,有没有一种方法可以一步完成从const void*unsigned char*的转换?

2 个答案:

答案 0 :(得分:3)

使用C样式强制转换将生成相同的程序集。 As seen in Compiler Explorer

//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-性是有意和期望的行为。代码维护人员应该查看这些强制转换,并假定代码背后有意图,而不必猜测您是否知道直接从const void*unsigned char*的强制转换会带来未定义行为的风险。您的示例可能不包含UB(因为您已指定transfer的协定是在data为0时将direction视为只读),但是对于任何其他需要对您的代码进行更改可以理解您的编码实践的故意。

答案 1 :(得分:0)

您不希望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的建议...