Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code using fmt::format breaks after Visual Studio 2022 Update 17.4

I am using fmt::format from the fmtlib extensively. After updating Visual Studio 2022 from 17.3.5 to 17.4.0 I have a problem in Release Builds with Code like the following:

const std::string s1 = format("{}.{}", "abc", "test" );

While s1 and s1.c_str() is "abc.test" in Debug Builds, in Release Builds using fmtlib only s1 is "abc.test" and s1.c_str() returns "abc.test" followed by some garbage (e.g. "abc.testð_àô").

I have written a small test program:

#include <iostream>
#include <string>
#ifdef USE_STD_FORMAT
#include <format>
using std::format;
#else
#include <fmt/format.h>
using fmt::format;
#endif

void check(const std::string& s, const std::string& expected)
{
    if (s != expected)
        std::cout << "FAILED I: '" << s << "' != '" << expected << "'\n";
    else if (strcmp(s.c_str(), expected.c_str()) != 0)
        std::cout << "FAILED II: '" << s.c_str() << "' != '" << expected.c_str() << "'\n";
}

void test(const char* p1, const char* p2)
{
    const std::string s1 = format("{}.{}", p1, p2);
    const std::string s2 = std::string(p1).append(".").append(p2);

    check(s1, s2.c_str());
}

int main()
{
    std::cout << "_MSC_FULL_VER: " << _MSC_FULL_VER << "\n";
#if USE_STD_FORMAT
    std::cout << "using std::format\n";
#else
    std::cout << "using fmt::format\n";
#endif

    test("abc", "test");
    test("abc", "test");
}

Built with VS2022 17.3.5 the output is:

C:\Temp\VS2022_17.4\x64>C:\Temp\VS2022_17.4\x64\Debug\VS2022_17.4.exe
_MSC_FULL_VER: 193331630
using fmt::format

C:\Temp\VS2022_17.4\x64>C:\Temp\VS2022_17.4\x64\Release\VS2022_17.4.exe
_MSC_FULL_VER: 193331630
using fmt::format

C:\Temp\VS2022_17.4\x64>C:\Temp\VS2022_17.4\x64\Release_StdFormat\VS2022_17.4.exe
_MSC_FULL_VER: 193331630
using std::format

Build with VS2022 17.4.0 the output is

C:\temp\VS2022_17.4\x64>C:\temp\VS2022_17.4\x64\Debug\VS2022_17.4.exe
_MSC_FULL_VER: 193431933
using fmt::format

C:\temp\VS2022_17.4\x64>C:\temp\VS2022_17.4\x64\Release\VS2022_17.4.exe
_MSC_FULL_VER: 193431933
using fmt::format
FAILED II: 'abc.testð_àô ' != 'abc.test'
FAILED II: 'abc.testð_àô ' != 'abc.test'

C:\temp\VS2022_17.4\x64>C:\temp\VS2022_17.4\x64\Release_StdFormat\VS2022_17.4.exe
_MSC_FULL_VER: 193431933
using std::format

Because it works with std::format in both Visual Studio versions and it works with VS2022 17.3.6 with both format versions I don't know if it is a problem in Visual Studio or in fmtlib or in my code.

like image 752
Stefan F. Avatar asked Aug 14 '26 23:08

Stefan F.


1 Answers

This is a bug in Microsoft STL, quoting https://developercommunity.visualstudio.com/t/Code-using-fmtlib-format-breaks-after-Vi/10198870:

The issue is that the constructor for std::string was not adding the null terminator itself so when being constructed with a char * that is not null terminated, c_str() will return garbage until a zero byte is hit.

like image 72
vitaut Avatar answered Aug 17 '26 12:08

vitaut