未使用的功能参数上的编译器优化

时间:2019-03-17 13:17:29

标签: c++ optimization rpc

在使用Windows RPC的几天里,我遇到了一个奇怪的问题。现在,我找到了解决方案,但我想知道什么是预防此问题的正确方法。

所以基本上我在调用NdrClientCall2函数时遇到问题。如您在文档中所见,该函数的第三个参数是指向客户端调用堆栈的指针。我将midl.exe生成的C代码更改为自己的C ++版本,因此我的调用者看起来像这样:

void CppRpc::InternalCommand(int pSize, char buffer[1000000]) const
{
    RpcTryExcept
    {
        NdrClientCall2(PMIDL_STUB_DESC(&m_rpc_stup_description),
            PFORMAT_STRING(&MIDL_PROCFORMAT_STRING.Format[0]),
            reinterpret_cast<unsigned char *>(&pSize));
    }
    RpcExcept(1)
    {
        std::cerr << "Runtime reported exception " << RpcExceptionCode()
            << std::endl;
    }
    RpcEndExcept
}

在使用完全优化的发布模式下,一两天出现访问冲突,然后我了解到,由于在此函数中未使用参数buffer,编译器优化会以某种方式删除此参数。

但是我需要将此参数放在堆栈中,以便NdrClientCall2可以将其流式传输到服务器。如果我将buffer的任何用法(例如char dummy = buffer[0];)添加到功能伙伴,那么它将正常工作。

所以我的问题是,如何防止这种情况下的优化? 我正在使用Visual Studio 2017。

1 个答案:

答案 0 :(得分:2)

我不建议您这样做。因为InternalCommand是您的内部函数,所以编译器可能会更改其参数的布局。而(据我所知)您需要特定的布局,其中有一个int变量,后跟为堆栈保留的缓冲区。

同样,如果您更改函数调用约定(即cdeclstdcall),则此布局可能也会更改。

我将用单个int字段定义一个结构(POD),将指向它的指针传递给您的函数,而调用者分配的实际结构则更大。

类似这样的东西:

struct StackFrame
{
    int pSize;
    char pStack[1000000]; // stack goes here
};

// ...

void CppRpc::InternalCommand(StackFrame* pStack) const
{
    RpcTryExcept
    {
        NdrClientCall2(PMIDL_STUB_DESC(&m_rpc_stup_description),
            PFORMAT_STRING(&MIDL_PROCFORMAT_STRING.Format[0]),
            reinterpret_cast<unsigned char *>(pStack));
    }
    RpcExcept(1)
    {
        std::cerr << "Runtime reported exception " << RpcExceptionCode()
            << std::endl;
    }
    RpcEndExcept
}