I've just pushed some changes to develop so that MSVC-14.0 update 3 no longer defines: BOOST_NO_CXX14_VARIABLE_TEMPLATES BOOST_NO_SFINAE_EXPR BOOST_NO_TWO_PHASE_NAME_LOOKUP As far as I can tell, these cause no new regressions in develop, please let me know if I've missed something. I haven't stopped defining BOOST_NO_CXX11_CONSTEXPR as it causes new failures: * Multiprecision, one new failure when using constexpr features, looks harmless. * Metaparse, causes the compiler to run out of resources on a couple of tests - these test non-default values of BOOST_METAPARSE_LIMIT_STRING_SIZE and are probably harmless. * Type_erasure, causes one new runtime failure. * Chrono, nothing much compiles - this one is the showstopper and needs investigating - any takers? Best, John.
On Sun, Jul 3, 2016 at 4:25 AM, John Maddock
I've just pushed some changes to develop so that MSVC-14.0 update 3 no longer defines:
BOOST_NO_CXX14_VARIABLE_TEMPLATES
BOOST_NO_SFINAE_EXPR
BOOST_NO_TWO_PHASE_NAME_LOOKUP
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet. Are you sure that it really is working:-? OTOH, config isn't meant to be a conformance test, so if lack of two-phase lookup is not a problem for Boost code, maybe we should not define it. Because Boost code has to work on clang and gcc, it doesn't surprise me that you didn't hit any new regressions. Thanks for working this, --Beman
On 03/07/2016 16:07, Beman Dawes wrote:
On Sun, Jul 3, 2016 at 4:25 AM, John Maddock
wrote: I've just pushed some changes to develop so that MSVC-14.0 update 3 no longer defines:
BOOST_NO_CXX14_VARIABLE_TEMPLATES
BOOST_NO_SFINAE_EXPR
BOOST_NO_TWO_PHASE_NAME_LOOKUP
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
Are you sure that it really is working:-?
Nope, but it passes our cursory test case, and no one is actually using it anyway! Suggest we revisit as and when the need arises? John.
OTOH, config isn't meant to be a conformance test, so if lack of two-phase lookup is not a problem for Boost code, maybe we should not define it.
Because Boost code has to work on clang and gcc, it doesn't surprise me that you didn't hit any new regressions.
Thanks for working this,
--Beman
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost .
On Sun, Jul 3, 2016 at 12:17 PM, John Maddock
On 03/07/2016 16:07, Beman Dawes wrote:
On Sun, Jul 3, 2016 at 4:25 AM, John Maddock
wrote: I've just pushed some changes to develop so that MSVC-14.0 update 3 no
longer defines:
BOOST_NO_CXX14_VARIABLE_TEMPLATES
BOOST_NO_SFINAE_EXPR
BOOST_NO_TWO_PHASE_NAME_LOOKUP
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
Are you sure that it really is working:-?
Nope, but it passes our cursory test case, and no one is actually using it anyway!
Suggest we revisit as and when the need arises?
OK by me.
--Beman
[Beman Dawes]
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
That is correct. Here's proof, with our latest development build:
C:\Temp>type meow.cpp
#include
On 05/07/2016 17:44, Stephan T. Lavavej wrote:
[Beman Dawes]
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet. That is correct. Here's proof, with our latest development build:
Indeed, and our tests fail too - somehow I'd missed it - fixed now in develop. Thanks for the heads up, John.
C:\Temp>type meow.cpp #include
void f(int) { puts("Standard two-phase!"); }
template <typename T> void g(T t) { f(t); }
void f(double) { puts("Microsoft one-phase!"); }
int main() { printf("%02d.%02d.%05d.%02d\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000, _MSC_BUILD); g(3.14); }
C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp && meow meow.cpp 19.00.24229.00 Microsoft one-phase!
STL
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 6/07/2016 04:44, Stephan T. Lavavej wrote:
[Beman Dawes]
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
That is correct. Here's proof, with our latest development build:
C:\Temp>type meow.cpp #include
void f(int) { puts("Standard two-phase!"); }
template <typename T> void g(T t) { f(t); }
void f(double) { puts("Microsoft one-phase!"); }
int main() { printf("%02d.%02d.%05d.%02d\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000, _MSC_BUILD); g(3.14); }
C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp && meow meow.cpp 19.00.24229.00 Microsoft one-phase!
Out of curiosity, since I presume that the expectation is that a two-phase compiler would try to call f(int) instead -- why is this considered better? I assume it has something to do with the order of the definitions or with the name "f" technically not depending on the template arguments (but as a function call does depend on its parameters, and its parameters are dependent, it seems wiser to treat f as dependent so that overload resolution can truly work as expected). In particular, if the compiler did decide to use f(int) instead of f(double) in the code above, then it would generate a compiler error (or at least a warning, due to double-to-int being a lossy conversion and therefore requiring an explicit cast) instead of using the "right" overload. That's the sort of thing that would make me want to throw things at the compiler, not something I'd consider a feature. I must be missing something.
It is "better" as in it is "what the standard says". In g, f is not a dependent name. That means it gets resolved when the template is parsed, f(double) has been declared.
Billy3
________________________________
From: Boost
[Beman Dawes]
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
That is correct. Here's proof, with our latest development build:
C:\Temp>type meow.cpp #include
void f(int) { puts("Standard two-phase!"); }
template <typename T> void g(T t) { f(t); }
void f(double) { puts("Microsoft one-phase!"); }
int main() { printf("%02d.%02d.%05d.%02d\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000, _MSC_BUILD); g(3.14); }
C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp && meow meow.cpp 19.00.24229.00 Microsoft one-phase!
Out of curiosity, since I presume that the expectation is that a two-phase compiler would try to call f(int) instead -- why is this considered better? I assume it has something to do with the order of the definitions or with the name "f" technically not depending on the template arguments (but as a function call does depend on its parameters, and its parameters are dependent, it seems wiser to treat f as dependent so that overload resolution can truly work as expected). In particular, if the compiler did decide to use f(int) instead of f(double) in the code above, then it would generate a compiler error (or at least a warning, due to double-to-int being a lossy conversion and therefore requiring an explicit cast) instead of using the "right" overload. That's the sort of thing that would make me want to throw things at the compiler, not something I'd consider a feature. I must be missing something. _______________________________________________ Unsubscribe & other changes: https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2flists.boost.org%2fmailman%2flistinfo.cgi%2fboost&data=01%7c01%7cbion%40microsoft.com%7c9eff46a7fe07405b277508d3a53189fc%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=bb5c0HNq4RzbedPA7BHL4gZrpXFIjvJRwAG91fjOPH8%3d
[STL]
void f(int) { puts("Standard two-phase!"); } template <typename T> void g(T t) { f(t); } void f(double) { puts("Microsoft one-phase!"); }
[Billy O'Neal]
It is "better" as in it is "what the standard says".
Yes.
In g, f is not a dependent name.
Incorrect. f is a dependent name, because which f is selected depends on what T is. But two-phase isn't as simple as "look up non-dependent names immediately, look up dependent names late". The relevant Standardese is N4594 14.6.4 [temp.dep.res]/1: "In resolving dependent names, names from the following sources are considered: (1.1) - Declarations that are visible at the point of definition of the template. (1.2) - Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context." Here, 1.1 means that f(int) is visible when g() is defined, while f(double) has not yet been seen. 1.2 has the ability to see things that are declared after g()'s definition, BUT it is restricted to "associated namespaces" (like what's considered for ADL). Here, 3.14 is a double and has no associated namespaces, so nothing extra is considered. (It took me a long time to understand these rules, and I still don't have a very good intuition for them.) STL
On 05.07.2016 20:22, Stephan T. Lavavej wrote:
"In resolving dependent names, names from the following sources are considered: (1.1) - Declarations that are visible at the point of definition of the template. (1.2) - Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context."
Here, 1.1 means that f(int) is visible when g() is defined, while f(double) has not yet been seen.
1.2 has the ability to see things that are declared after g()'s definition, BUT it is restricted to "associated namespaces" (like what's considered for ADL). Here, 3.14 is a double and has no associated namespaces, so nothing extra is considered.
It isn't clear to me why the "global namespace" together with built-in (and other globally defined) types isn't considered the same way as any named namespace with the types defined inside it. At least, such a reading of the standard would resolve the above and remove the special treatment the global namespace gets in your interpretation.
(It took me a long time to understand these rules, and I still don't have a very good intuition for them.)
STL
Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...
[Stefan Seefeld]
It isn't clear to me why the "global namespace" together with built-in (and other globally defined) types isn't considered the same way as any named namespace with the types defined inside it. At least, such a reading of the standard would resolve the above and remove the special treatment the global namespace gets in your interpretation.
There is no room for interpretation here. N4594 3.4.2 [basic.lookup.argdep]/2.1: "If T is a fundamental type, its associated sets of namespaces and classes are both empty." Note that the Boost mailing list really isn't an appropriate place to discuss 18-year-old C++ Core Language design decisions. STL
On 6/07/2016 12:08, Billy O'Neal (VC LIBS) wrote:
It is "better" as in it is "what the standard says". In g, f is not a dependent name. That means it gets resolved when the template is parsed, f(double) has been declared.
That seems like a defect in interpretation or in the standard in that case. "f" is not dependent but f(<args that use T>) is. Given that there is no context (at least when known to be used as a callable) in which "f" by itself is a sensible identifier (if you try to take a pointer to it, in the presence of overloads you have to explicitly supply the intended argument types anyway), this just seems like it's trying to make life difficult for the programmer for no good reason. Again though I assume I'm missing something.
On 5 Jul 2016 at 16:44, Stephan T. Lavavej wrote:
[Beman Dawes]
I'm a bit surprised by the removal of BOOST_NO_TWO_PHASE_NAME_LOOKUP. My understanding, which certainly could be wrong, is that update 3 internally is doing some of the preliminary work that will enable two-phase name lookup eventually, but two-phase lookup isn't working yet.
That is correct. Here's proof, with our latest development build:
C:\Temp>type meow.cpp #include
void f(int) { puts("Standard two-phase!"); }
template <typename T> void g(T t) { f(t); }
void f(double) { puts("Microsoft one-phase!"); }
int main() { printf("%02d.%02d.%05d.%02d\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000, _MSC_BUILD); g(3.14); }
For anyone who has used MSVC for any length of time, we automatically write our code to ensure all overloads precede usage in order to ensure correct outcomes, sufficiently so many coming originally from MSVC-land are not aware MSVC is deficient on this. The fact so little Boost code requires two phase lookup was quite a surprise to me, but there you have it. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 7/07/2016 08:50, Niall Douglas wrote:
For anyone who has used MSVC for any length of time, we automatically write our code to ensure all overloads precede usage in order to ensure correct outcomes, sufficiently so many coming originally from MSVC-land are not aware MSVC is deficient on this. The fact so little Boost code requires two phase lookup was quite a surprise to me, but there you have it.
Well, it's natural C-ish coding style to at least declare symbols (including all overloads) before they're used, so most coding patterns wouldn't run into the difference. Where you're more likely to run into problems is if the library defines something that the user then further overloads -- but due to namespaces this would generally indicate a poor design if symbols have mixed implementations between library and user code. So library code is probably the least vulnerable to it. One of the common resolutions for cases where this sort of thing is needed is to use template specialisation (eg. a traits template such as std::hash) -- and using such a template with the parameter type T will *always* be a dependent type, so shouldn't have this issue anyway.
participants (7)
-
Beman Dawes
-
Billy O'Neal (VC LIBS)
-
Gavin Lambert
-
John Maddock
-
Niall Douglas
-
Stefan Seefeld
-
Stephan T. Lavavej