gpt4 book ai didi

c++ - 将编译时常量 vector 转换为堆分配版本

转载 作者:行者123 更新时间:2023-12-01 15:07:53 39 4
gpt4 key购买 nike

我发疯了Visual Studio的代码分析器。这行:

void Foo() {
const std::vector<uint8_t> bar{ /* 21,140 uint8_t entries */ };
//...
}

发出 C6262 warning:
Function uses 21140 bytes of stack: exceeds /analyze:stacksize`16384`. Consider moving some data to heap

vector 包含二进制文件的各个字节。在这种情况下,我的全部意图是不使用外部文件,因此数据始终可供函数调用者使用。

是否有一种简单的方法可以将编译时值转换为堆分配的值?

将声明从函数移出到静态文件级范围是非常昂贵和耗时的,因为A)永远不会释放内存,并且B)这只是使用多个大型二进制数组的十几个函数之一重命名它们并不能很好地扩展。

忽略警告也是不可能的。

编辑:

根据要求提供MCRE。 (“CR”是值得商bat的,因为它是300,000 LOC游戏引擎的一部分,但这无关紧要,因为CA在太大的 vector 的基本声明中失败了,所以这里是实际用法。) ShadowRanger's answer的注释,既没有将大 vector 声明为 static也没有声明 const static来解决问题,并且CA仍发出警告:

std::unique_ptr<ShaderProgram> Renderer::CreateDefaultShaderProgram() noexcept {
static std::vector<uint8_t> g_VertexFunction{ /* 5K entries */ };
static std::vector<uint8_t> g_DefaultPixelFunction{ /* 21,140 entries */ };
// /\/\ Code Analysis warns here at g_DefaultPixelFunction declaration.

ShaderProgramDesc desc{};
desc.name = "__default";
desc.device = _rhi_device.get();
{
ID3D11VertexShader* vs = nullptr;
_rhi_device->GetDxDevice()->CreateVertexShader(g_VertexFunction.data(), g_VertexFunction.size(), nullptr, &vs);

ID3DBlob* blob = nullptr;
::D3DCreateBlob(g_VertexFunction.size(), &blob);
std::memcpy(blob->GetBufferPointer(), g_VertexFunction.data(), g_VertexFunction.size());

g_VertexFunction.clear();
g_VertexFunction.shrink_to_fit();

desc.vs = vs;
desc.vs_bytecode = blob;
desc.input_layout = _rhi_device->CreateInputLayoutFromByteCode(blob);
}
{
ID3D11PixelShader* ps = nullptr;
_rhi_device->GetDxDevice()->CreatePixelShader(g_DefaultPixelFunction.data(), g_DefaultPixelFunction.size(), nullptr, &ps);

ID3DBlob* blob = nullptr;
::D3DCreateBlob(g_DefaultPixelFunction.size(), &blob);
std::memcpy(blob->GetBufferPointer(), g_DefaultPixelFunction.data(), g_DefaultPixelFunction.size());

g_DefaultPixelFunction.clear();
g_DefaultPixelFunction.shrink_to_fit();

desc.ps = ps;
desc.ps_bytecode = blob;
}
return std::make_unique<ShaderProgram>(std::move(desc));
}

编辑2:

按照 Jeff Garrett's answer,解决方案是事先将初始化列表变量声明为静态(const,因为“Const all Things!”)。

const static std::initializer_list<uint8_t> vs_init_list{/*5K entries*/};
std::vector<uint8_t> g_VertexFunction{vs_init_list};

const static std::initializer_list<uint8_t> ps_init_list{/*21K entries*/};
std::vector<uint8_t> g_PixelFunction{ps_init_list};

//... Same as before

最佳答案

vector 的堆栈空间不取决于其大小。

正在使用std::initializer_list初始化 vector 。那就是需要潜在的堆栈空间的原因。那就是你可以使之静态的。

关于c++ - 将编译时常量 vector 转换为堆分配版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62206131/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com