Issue 2989: path's stream insertion operator lets you insert everything under the sun (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
2989. path's stream insertion operator lets you insert everything under the sun
Section: 31.12.6.7 [fs.path.io] Status: C++20 Submitter: Billy O'Neal III Opened: 2017-06-27 Last modified: 2021-02-25
Priority: 2
View all issues with C++20 status.
Discussion:
The rules for converting a path to a narrow character sequence aren't necessarily the same as that iostreams should use. Note that this program creates a temporary path and stream inserts that, which likely destroys information.
#include #include #include
void foo() { using namespace std; using namespace std::experimental::filesystem::v1; wstring val(L"abc"); std::cout << val; }
Using the godbolt online compiler we get:
foo PROC sub rsp, 104 ; 00000068H lea rdx, OFFSET FLAT:$SG44895 lea rcx, QWORD PTR val$[rsp] call std::basic_string<wchar_t,std::char_traits,std::allocator >::basic_string<wchar_t,std::char_traits,std::allocator > lea rdx, QWORD PTR val$[rsp] lea rcx, QWORD PTR $T1[rsp] call ??$?0_WU?$char_traits@_W@std@@V?$allocator@_W@1@@path@v1@filesystem@experimental@std@@QEAA@AEBV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@4@@Z lea rdx, QWORD PTR $T1[rsp] lea rcx, OFFSET FLAT:std::cout call std::experimental::filesystem::v1::operator<<<char,std::char_traits > lea rcx, QWORD PTR $T1[rsp] call std::experimental::filesystem::v1::path::
path lea rcx, QWORD PTR val$[rsp] call std::basic_string<wchar_t,std::char_traits,std::allocator >::basic_string<wchar_t,std::char_traits,std::allocator > add rsp, 104 ; 00000068H ret 0 foo ENDP
This should either be disabled with a SFINAE constraint, use the auto_ptr user-defined conversion trick, or the stream insertion operators should be made "hidden friends" to prevent conversions to pathfrom being considered here.
[2017-07 Toronto Monday issue prioritization]
Priority 2
[2017-07 Toronto Saturday afternoon]
LWG confirmed they want the hidden friend solution, Billy O'Neal to provide wording.
[2018-1-26 issues processing telecon]
Status to 'Tentatively Ready'
[2018-3-17 Adopted in Jacksonville]
Proposed resolution:
This resolution is relative to N4659.
- Edit 31.12.4 [fs.filesystem.syn], header
<filesystem>synopsis, as indicated:// 31.12.6.7 [fs.path.io], path inserter and extractortemplate <class charT, class traits>basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const path& p);template <class charT, class traits>basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, path& p); - Edit 31.12.6.7 [fs.path.io] as indicated:
[Drafting note: The project editor is kindly asked to consider to move sub-clause 31.12.6.7 [fs.path.io] before sub-clause 31.12.6.8 [fs.path.nonmember] (as a peer of it) — _end drafting note_]
template <class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const path& p);[…]
template <class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, path& p); - Edit 31.12.6 [fs.class.path] p2, class
pathsynopsis, as indicated:namespace std::filesystem {
class path {
public:
[…]
iterator begin() const;
iterator end() const;// 31.12.6.7 [fs.path.io] path inserter and extractor
template <class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const path& p);template <class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, path& p);
};
}