c++visual-c++stdvectortbbprecompiled-headers

Visual Studio generated suspicious assembly code when a oneAPI TBB header is present in a PCH


After building the code shown below in Visual Studio 2022 version 17.7.6 and running it, an exception std::length_error is thrown within MS C++ STL implementation. It attempts to create a vector using size_t( -1 ) as a size parameter.

//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

#pragma once
#include <tbb/parallel_for.h>

Interestingly, disabling the Additional Security Checks (/sdl) fixes the problem.

Both Release and Debug builds are affected with any Runtime Library setting: /MT, /MTd, /MD, /MDd.

The presence of Intel's Threading Building Blocks (TBB) header alone is enough to trigger this behavior - no linking to TBB is needed. TBB library was taken from the latest vcpkg at the time with the version 2021.10.0#3.

Is it a bug in Visual Studio, or is it some incompatibility between TBB and Additional Security Checks?

Here is the assembly. Release configuration:

    std::vector<int> vs(foo() + 1);
00007FF79AF822C3  call        std::vector<int,std::allocator<int> >::_Xlength (07FF79AF81C70h)  

Call to foo() is inlined and it throws immediately.

Debug configuration:

    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)  

This piece is suspicious:

00007FF7ACC74408  mov         rcx,0FFFFFFFFFFFFFFFFh  
00007FF7ACC7440F  cmovb       rax,rcx  

The full solution is available on a GitHub


Solution

  • This issue was reported to Microsoft: https://developercommunity.visualstudio.com/t/Wrong-code-produced-in-case-of-precompil/10507813

    And just today they responded that

    A fix for this issue has been released!

    And indeed it looks like the issue is not reproducible anymore in the latest Visual Studio 2022 Version 17.11.2.