1

I can compute a const char* presentation of an std::filesystem::path variable like that:

std::filesystem::path path1(L"ConsoleApplication1.cpp");
std::string strPath1 = path1.string();
const char* charArrPath1 = strPath1.c_str();

But if I omit explicit assignment of a string variable and use method chaining in a char array initialization statement

const char* charArrPath1 = path1.string().c_str();

variable charArrPath1 contains garbage after execution.

How come the chaining of methods seemingly fails to work?

PS If I explicitly assign the result of string() on path1 to some unrelated variable after initialization of charArrPath1, I do have the result as expected:

std::filesystem::path path1(L"ConsoleApplication1.cpp");
const char* charArrPath1 = path1.string().c_str();
std::string strPathUnrelated = path1.string();
std::cout << charArrPath1 << std::endl;

EPILEGOMENON:

The method chaining seems to fail when the code is run in x86 configurations, both Debug and Release. When run in an x64 Release configuration, the following program

#include <iostream>
#include <filesystem>

int main()
{
    std::filesystem::path path1(L"ConsoleApplication1.cpp");
    const char* charArrPath1 = path1.string().c_str();

    std::cout << charArrPath1 << std::endl;
}

prints out

ConsoleApplication1.cpp

Does anyone have an explanation for this behavior?

V.V.T
  • 231
  • 1
  • 7

2 Answers2

2

Because std::filesystem::path::string returns by-value, what it returns is a temporary, which will be destroyed after the full expression, left the pointer got from c_str() dangled.

As you've tried, the pointer won't be dangled if you use a named variable, which won't be destroyed immediately.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

"Dangling pointers is the darkest nightmare of a language that relies on pointers and explicit release of resources" (from `A brief introduction to C++'s model for type- and resource-safety' by Bjarne Stroustrup and Herb Sutter, section 3. Memory safety, p. 4)

Chasing a seemingly intermittent bug of my rather biggish program, I eventually found it brute-force, iterating over breakpoints. It happened to hide in rather obscure lines that construct filesystem path hints in a rarely executed branch. I wondered why 'Code Analysis', an awesome instrument to enforce type- and resource-safety of your code that you launch checking 'Enable Code Analysis on Build' in Visual Studio's project properties, failed to warn me of these lines, and posted a cautious question to Stack Overflow in a hope that someone teach me to use Code Analysis.

Curious, I also started to browse MSDN documentation and learnt that a Microsoft Native Recommended Rules ruleset, a default for C++ projects, does not contain the entire C++ Core Guideline set. I selected a Microsoft All Rules ruleset, run it against the old version of my program, and it flagged culprit lines with warnings C26486 Don't pass a pointer that may be invalid to a function.

As for PS and 'Epilegomenon' sections of my question, I found out that the reported behavior for different configurations is valid only for the v142 platform toolset, and (probably) is of a minor significance.

V.V.T
  • 231
  • 1
  • 7