filesystem path{}.string() interface brittle when developing cross platform
Firstly, I would like to than the author/s of filesystem for their great work and their time. I've recently written some code on Linux where I had to adapt a filesystem::path object to string. I noticed that the return value was of type [const std::string&], and used the same return value in my getter that exposed the underlying string. Moving over to windows, I had strange crashes (undefined behaviour) as result of the type under windows being converted to [std::string]. The reason for the "undefined behaviour" took me a while to figure out. While understanding why the author returned by value (Windows API underlying type not a std::string...), I think that for a specific type, the contract concerning return value "semantics" should no be broken. There is a significant difference between returning by const reference as opposed to returning by value. If the contract cannot be held, the decision should be made to (in the interest of consistency/clarity) to return the same type for all OS's/platforms if the code is to be considered platform independent. This might mean to compromise by returning by value, or to, in the case of Windows (where the underlying string has a different type), cache the string, or at the very least document a *BOLD* note that caution must be taken. I can comprehend that if conversion is required, return by value is the only option. I expect type consistency per type, as this to me is part of the contract of a function. I don't consider this a bug, but would appreciate some response. Kind Regards
On 3/06/2016 20:04, Werner Erasmus wrote:
I've recently written some code on Linux where I had to adapt a filesystem::path object to string. I noticed that the return value was of type [const std::string&], and used the same return value in my getter that exposed the underlying string. Moving over to windows, I had strange crashes (undefined behaviour) as result of the type under windows being converted to [std::string]. The reason for the "undefined behaviour" took me a while to figure out.
While I don't disagree with anything that you said in the unquoted parts of your message, the compiler should have generated a warning ("returning temporary by reference" or similar) in your getter method when compiling on Windows. The problem should have been discoverable this way.
Hello,
Sorry for late reply - I just now run accidentally into this thread.
On 03.06.2016 11:04, Werner Erasmus wrote:
While understanding why the author returned by value (Windows API underlying type not a std::string...), I think that for a specific type, the contract concerning return value "semantics" should no be broken. There is a significant difference between returning by const reference as opposed to returning by value. If the contract cannot be held, the decision should be made to (in the interest of consistency/clarity) to return the same type for all OS's/platforms if the code is to be considered platform independent. This might mean to compromise by returning by value, or to, in the case of Windows (where the underlying string has a different type), cache the string, or at the very least document a *BOLD* note that caution must be taken.
I can comprehend that if conversion is required, return by value is the only option. I expect type consistency per type, as this to me is part of the contract of a function.
Documentation says that string() returns by value. In old docs, there is a remark that string() is allowed to return by reference, depending on platform: http://www.boost.org/doc/libs/1_50_0/libs/filesystem/doc/reference.html#stri...
If string_type is the same type as the function's return type, the function is permitted to return by const& rather than const value. [Note: For POSIX, this occurs for string(), for Windows, wstring(). --end note]
Looks like in the new docs (at least in 1.61) the remark is removed.
I don't consider this a bug, but would appreciate some response.
Kind Regards
-- -------- Mitsyn Sergey --- Это сообщение проверено на вирусы антивирусом Avast. https://www.avast.com/antivirus
participants (3)
-
Gavin Lambert
-
Sergey Mitsyn
-
Werner Erasmus