-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Turn off BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS for MSVC++ #57
Conversation
Boost is attempting to use a function not in the standard, seekpos(), guarded by this setting. Looks like Boost can use the standards conforming interface for MSVC++ instead. It should work going back effectively "forever" as far as MSVC++ is concerned, but this guard applies the change only to 2017. It's possible there is a better control in boost.config I missed.
The question is how we should be targeting vc++ 14.1 ? I think we should use BOOST_MSVC from config, which holds the value of vc++'s _MSC_VER. Using a recent macro to identify a version of the vc++'s standard library seems very chancy to me. |
|
I would not use _MSC_VER directly in your PR but specifically BOOST_MSVC. This is because some other compilers, which are not vc++, also define _MSC_VER whereas BOOST_MSVC means that vc++ specifically is being used. Also are you really saying that newer versions of vc++ could be used with old versions of your C++ standard library ? I did not think that was possible in Microsoft distributions. When you say that 'Boost can use the standards conforming interface for MSVC++ instead. It should work going back effectively "forever" as far as MSVC++ is concerned' do you mean that all older versions of VC++, with their distributed versions of the C++ standard library, have a standards conforming interface as far as this problem is concerned ? That would be strange as it would put in question the original reason for the vc++ specific code in this particular situation. |
Yes, its a thing people do sometimes. Old libs with new compiler should work, old compiler with new libs is unsupported.
Modulo bugs, yes. I only tested with 2017 though which is why I so guarded it that way.
The Dinkumware code path is used for other Dinkumware licensees; they have this behavior of "call fsetpos followed by fseek" because the C standard says it's UB to call fsetpos on anything not returned by a call to fgetpos. (See C11, 7.21.9.3 "The fsetpos function"/2) But Dinkumware's caution there happens to be unnecessary for at least our current CRT implementation, where fsetpos just sets a 64 bit offset. There are some bugs that happened with VS 2017 15.7 and earlier where directly comparing fpos instances with non- |
Also note that the non-Dinkumware path in Boost already deals with this problem by directly casting the fpos to streamoff first. |
The original code path is for Dinkumware rather than for vc++ specifically. If you are saying that vc++ always worked correctly with Dinkumware and did not need this one-off code path we could remove it for any version of vc++ by just checking if BOOST_MSVC is defined. But to be more conservative than that, in order not to destroy the use of iostreams for past versions of vc++ other than the present one, I am fine with approving your PR as long as _MSVC_STL_VERSION is never used by any other compiler, which I assume and hope will be the case, without checking for BOOST_MSVC. To be really conservative though it might be best to check for both _MSVC_STL_VERSION and BOOST_MSVC as a reason to not use the code path. Can you change it appropriately to do that or do you want me to merge the PR and do it myself ? BOOST_MSVC is defined whenever vc++ is the compiler and not defined otherwise. |
I was just informed last night that there's a Boost.IOStreams test failing right now; let me investigate and I'll keep you posted. Thanks! |
Turns out the test failure is because I broke basic_stringbuf::seekoff last week :/, so not related to this change. I'll make the change you requested to test BOOST_MSVC first as soon as I hear I haven't broken boost.iostream any more. :) |
OK, confirmed that it's just because I made seekoff corrupt basic_stringbuf which I just fixed. (Yay, thank you boost iostreams tests for catching my mistake!) Updated PR with the additional test you requested. |
Could this be merged to master please? This is needed for VS 2017 Update 8 as of Preview 3.0. |
As the original author of the workarounds in boost/iostreams/positioning.hpp, I can confirm they absolutely were necessary back when I produced them in 2005, but that's a long time ago now, even for Boost. ;-) |
I apologize on behalf of my predecessors? :P |
No so long ago, this was only fixed in VS 2012, see https://groups.google.com/forum/#!searchin/boost-developers-archive/_FPOSOFF%7Csort:date/boost-developers-archive/VT7UxdJwfn4/MXpi6gyoBAAJ for some more discussion |
Wait wait wait wait we cast it to long? WHY?!???! :( |
Before VS2010 lots of ugly hacks were required for seeking past 2GB in std::fstream for similar reasons. |
…eekpos() with VS 15.8 Change taken from boostorg/iostreams#57, but this is not yet included in a boost release.
Any idea when this will be released? |
This should appear in 1.69.0 - I think it was supposed to be in 1.68.0 but wasn't merged in time. It is in the pipeline now. |
I'm receiving the same error in iostreams/positioning.hpp. Make sure y'all check and double check your regression before making that commit and/or merging, please. |
@mwpowellhtx That should be guarded by the ifdef here?
|
@BillyONeal It's a good question, it is, but how do I know whether I have "Dinkumware fpos"? Meanwhile, I am defining |
@mwpowellhtx It would be more appropriate to call it "workaround broken Dinkumware behavior where they put file sizes into an int" :) |
@BillyONeal Copy that; I understand. 👍 I installed the patch, BTW, and it appears to be working. I still have to "acknowledge" the issue, so to speak, but at least I can proceed forward. |
@BillyONeal |
Boost stopped using `_FPOSOFF` when boostorg/iostreams@7c2592c was merged on 2016-09-16. I've verified that this shipped in Boost 1.63.0 on 2016-12-26. We deprecated `std::fpos::seekpos()` with MSVC-PR-132953 merged on 2018-07-18. (We first noticed the problem when MSVC-PR-115404 was merged on 2018-04-11.) Boost stopped using it when boostorg/iostreams#57 was merged on 2018-04-20. I've verified that this shipped in Boost 1.69.0 on 2018-12-12. Note that while the `std::fpos` type appears in the parameter types and return types of dllexported functions, `std::fpos` is not dllexported itself, as indicated by the lack of explicit calling conventions in the source. Because `std::fpos::seekpos()` isn't dllexported, we can freely remove it. (The only mentions of `seekpos` in the dllexport surface are for the different `std::basic_streambuf::seekpos()`, which conveniently also demonstrates how it takes and returns `std::fpos`.) ``` D:\GitHub\STL\out\x64\out\bin\amd64>dumpbin /exports msvcp140d_oss.dll | rg "\bseekpos\b" 1206 4B5 00053D70 ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<char,struct std::char_traits<char> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1207 4B6 00053DB0 ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<unsigned short,struct std::char_traits<unsigned short> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1208 4B7 00053DF0 ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<wchar_t,struct std::char_traits<wchar_t> >::seekpos(class std::fpos<struct _Mbstatet>,int)) ```
Boost stopped using `_FPOSOFF` when boostorg/iostreams@7c2592c was merged on 2016-09-16. I've verified that this shipped in Boost 1.63.0 on 2016-12-26. We deprecated `std::fpos::seekpos()` with MSVC-PR-132953 merged on 2018-07-18. (We first noticed the problem when MSVC-PR-115404 was merged on 2018-04-11.) Boost stopped using it when boostorg/iostreams#57 was merged on 2018-04-20. I've verified that this shipped in Boost 1.69.0 on 2018-12-12. Note that while the `std::fpos` type appears in the parameter types and return types of dllexported functions, `std::fpos` is not dllexported itself, as indicated by the lack of explicit calling conventions in the source. Because `std::fpos::seekpos()` isn't dllexported, we can freely remove it. (The only mentions of `seekpos` in the dllexport surface are for the different `std::basic_streambuf::seekpos()`, which conveniently also demonstrates how it takes and returns `std::fpos`.) ``` D:\GitHub\STL\out\x64\out\bin\amd64>dumpbin /exports msvcp140d_oss.dll | rg "\bseekpos\b" 1206 4B5 00053D70 ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<char,struct std::char_traits<char> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1207 4B6 00053DB0 ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<unsigned short,struct std::char_traits<unsigned short> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1208 4B7 00053DF0 ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<wchar_t,struct std::char_traits<wchar_t> >::seekpos(class std::fpos<struct _Mbstatet>,int)) ```
Boost stopped using `_FPOSOFF` when boostorg/iostreams@7c2592c was merged on 2016-09-16. I've verified that this shipped in Boost 1.63.0 on 2016-12-26. We deprecated `std::fpos::seekpos()` with MSVC-PR-132953 merged on 2018-07-18. (We first noticed the problem when MSVC-PR-115404 was merged on 2018-04-11.) Boost stopped using it when boostorg/iostreams#57 was merged on 2018-04-20. I've verified that this shipped in Boost 1.69.0 on 2018-12-12. Note that while the `std::fpos` type appears in the parameter types and return types of dllexported functions, `std::fpos` is not dllexported itself, as indicated by the lack of explicit calling conventions in the source. Because `std::fpos::seekpos()` isn't dllexported, we can freely remove it. (The only mentions of `seekpos` in the dllexport surface are for the different `std::basic_streambuf::seekpos()`, which conveniently also demonstrates how it takes and returns `std::fpos`.) ``` D:\GitHub\STL\out\x64\out\bin\amd64>dumpbin /exports msvcp140d_oss.dll | rg "\bseekpos\b" 1206 4B5 00053D70 ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@DU?$char_traits@D@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<char,struct std::char_traits<char> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1207 4B6 00053DB0 ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@GU?$char_traits@G@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<unsigned short,struct std::char_traits<unsigned short> >::seekpos(class std::fpos<struct _Mbstatet>,int)) 1208 4B7 00053DF0 ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z = ?seekpos@?$basic_streambuf@_WU?$char_traits@_W@std@@@std@@Meaa?AV?$fpos@U_Mbstatet@@@2@V32@H@Z (protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_streambuf<wchar_t,struct std::char_traits<wchar_t> >::seekpos(class std::fpos<struct _Mbstatet>,int)) ```
Boost is attempting to use a function not in the standard, seekpos(),
guarded by this setting. Looks like Boost can use the standards
conforming interface for MSVC++ instead. It should work going
back effectively "forever" as far as MSVC++ is concerned, but this
guard applies the change only to 2017. It's possible there is a better
control in boost.config I missed.