含oneAPI TBB头的PCH在VS中引发std::length_error异常问题咨询
TBB头文件与VS安全检查选项导致vector构造异常分析
问题现象
在Visual Studio 2022 17.7.6版本中编译运行以下代码时,MS C++ STL会抛出std::length_error异常,原因是代码尝试以size_t(-1)作为参数创建std::vector。
代码示例
main.cpp
//main.cpp #include "stdafx.h" #include <windows.h> #include <vector> #include <iostream> int foo() { return -1; } int main() { std::vector<int> vs(foo() + 1); std::cout << vs.size() << std::endl; return 0; }
stdafx.h
//stdafx.h #pragma once #include <tbb/parallel_for.h>
触发与缓解条件
- 启用**Additional Security Checks (/sdl)**编译选项时会触发异常,禁用该选项则问题消失
- Release和Debug构建模式下,所有Runtime Library设置(
/MT、/MTd、/MD、/MDd)均受此问题影响 - 仅引入Intel Threading Building Blocks (TBB)的
<tbb/parallel_for.h>头文件即可触发该行为,无需链接TBB库(测试使用vcpkg的2021.10.0#3版本)
汇编代码分析
Release配置汇编片段
std::vector<int> vs(foo() + 1); 00007FF79AF822C3 call std::vector<int,std::allocator<int> >::_Xlength (07FF79AF81C70h)
foo()调用被内联,代码会立即抛出异常。
Debug配置汇编片段
std::vector<int> vs(foo() + 1); 00007FF7ACC743DD mov edx,20h 00007FF7ACC743E2 lea rcx,[vs] 00007FF7ACC743E6 call std::vector<int,std::allocator<int> >::__autoclassinit2 (07FF7ACC712E9h) 00007FF7ACC743EB lea rcx,[rbp+104h] 00007FF7ACC743F2 call std::allocator<int>::allocator<int> (07FF7ACC714A1h) 00007FF7ACC743F7 mov qword ptr [rbp+138h],rax 00007FF7ACC743FE call foo (07FF7ACC713D9h) 00007FF7ACC74403 add eax,1 00007FF7ACC74406 mov eax,eax 00007FF7ACC74408 mov rcx,0FFFFFFFFFFFFFFFFh 00007FF7ACC7440F cmovb rax,rcx 00007FF7ACC74413 mov rcx,qword ptr [rbp+138h] 00007FF7ACC7441A mov r8,rcx 00007FF7ACC7441D mov rdx,rax 00007FF7ACC74420 lea rcx,[vs] 00007FF7ACC74424 call std::vector<int,std::allocator<int> >::vector<int,std::allocator<int> > (07FF7ACC714F6h)
其中可疑的代码片段为:
00007FF7ACC74408 mov rcx,0FFFFFFFFFFFFFFFFh 00007FF7ACC7440F cmovb rax,rcx
这段代码会在foo()+1(即-1+1=0)的结果被转换为无符号类型时,错误地将其替换为size_t(-1),最终导致vector构造时触发长度校验异常。
疑问
这是Visual Studio的Bug,还是TBB与Additional Security Checks编译选项的兼容性问题?
内容的提问来源于stack exchange,提问作者gbg
相关产品推荐
相关产品推荐

