I apologize for this non-Boost related post, but I ran into what I
thought was a C++17 bug in clang ( also in vc++14.2 C++17 ), whose explanation to me of why it is not a bug really sounds like the non-logic of "Alice in Wonderland". I am not putting down the person who explains to me why it is not a bug in any way, as I know he is a C++ expert, but if this is really C++17 something must be wrong with my admittedly limited understanding of C++ and where it is going. My bug report is at https://bugs.llvm.org/show_bug.cgi?id=49684 and the explanation given there just eludes me as to what C++17 is doing, as my further comments makes apparent. Does anyone actually understand how this can possibly be ? How does C++17 apparently deduce a template argument different from what the actual type is and than declare therefore a mismatch ? This is really something from another world. My apologies for bringing this up in Boost, as it is purely a C++ issue, but my original problem comes from something I have been working on in the hopes it might eventually be a Boost library, so I decided to see if any of the expert Boost contributors might know what is going on in C++17. I realize that if everyone did as I have done here the mailing list would be a mass of irrelevant posts not Boost related. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
On Tue, Mar 23, 2021 at 5:13 PM Edward Diener via Boost
<[hidden email]> wrote: Hello Edward, > I apologize for this non-Boost related post, but I ran into what I > thought was a C++17 bug in clang ( also in vc++14.2 C++17 ), whose > explanation to me of why it is not a bug really sounds like the > non-logic of "Alice in Wonderland". [snip] > My bug > report is at https://bugs.llvm.org/show_bug.cgi?id=49684 and the > explanation given there just eludes me as to what C++17 is doing, [snip] Aren't consts ignored in function parameters? Then the parameter is not const and you have a mismatch. Can't you use different parameter types and use SFINAE by comparing the two after removing const? Kind regards, -- Felipe Magno de Almeida Owner @ Expertise Solutions www: https://expertise.dev phone: +55 48 9 9681.0157 LinkedIn: in/felipealmeida _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
Am 23.03.2021 um 21:13 schrieb Edward Diener via Boost:
> I apologize for this non-Boost related post, but I ran into what I > thought was a C++17 bug in clang ( also in vc++14.2 C++17 )... In a template of form template<class T, bool (*)(T)> whatever up until C++14, the function argument type in the non-type template parameter was never looked at in the deduction of type T because NTTPs weren't deemed dependent on placeholder types in their function arguments. Beginning with C++17, they are. Therefore you may get conflicting type deduction because the second, additional deduction path from the function argument type in the NTTP will never deduce a top-level cv-qualified T in case of non-reference-like arguments. But the first, formerly only deduction path, may. And therein lies the conflict in your example where T = const char in the first path and T = char is in the second. Well, at least this is my understanding of P0172. Ciao Dani -- PGP/GPG: 2CCB 3ECB 0954 5CD3 B0DB 6AA0 BA03 56A1 2C4638C5 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
On 3/24/2021 4:41 AM, Daniela Engert via Boost wrote:
> Am 23.03.2021 um 21:13 schrieb Edward Diener via Boost: >> I apologize for this non-Boost related post, but I ran into what I >> thought was a C++17 bug in clang ( also in vc++14.2 C++17 )... > > In a template of form > > template<class T, bool (*)(T)> whatever > > up until C++14, the function argument type in the non-type template > parameter was never looked at in the deduction of type T because NTTPs > weren't deemed dependent on placeholder types in their function > arguments. Beginning with C++17, they are. Therefore you may get > conflicting type deduction because the second, additional deduction path > from the function argument type in the NTTP will never deduce a > top-level cv-qualified T in case of non-reference-like arguments. But > the first, formerly only deduction path, may. And therein lies the > conflict in your example where T = const char in the first path and T = > char is in the second. > > Well, at least this is my understanding of P0172. I appreciate your explanation, and the following is not directed at you personally: What is there to deduce ? If I specify whatever<char const,nullptr> then T is 'char const'. It's right there in my instantiation. Making it impossible in this simple situation to specify the T type when it is a top-level const type can not be C++ in any logical sense. I also do not even begin to understand why 'bool (*)(char const)' becomes 'bool (*)(char)' in any logical world. Clearly a char const is not the same as a char. Who in their right minds would make up a rule that says they are the same, whether in a function declaration or not ? They clearly are not, unless you are out to destroy the notion that top-level consts in function declarations mean anything. Honestly if this is now C++, something seriously has gone wrong AFAICS. No doubt I am missing something basic, but this is truly "Alice in Wonderland" stuff to me. OK, I have had my rant. In what I was working on I will just specify that T as a top-level const is disallowed. My design can get by on that, rather than come up with some tortured code that allows T as a top-level const in the sort of signature above which works in both C++14 and C++17 on up. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
On 3/24/2021 12:42 AM, Felipe Magno de Almeida via Boost wrote:
> On Tue, Mar 23, 2021 at 5:13 PM Edward Diener via Boost > <[hidden email]> wrote: > > Hello Edward, > >> I apologize for this non-Boost related post, but I ran into what I >> thought was a C++17 bug in clang ( also in vc++14.2 C++17 ), whose >> explanation to me of why it is not a bug really sounds like the >> non-logic of "Alice in Wonderland". > > [snip] > >> My bug >> report is at https://bugs.llvm.org/show_bug.cgi?id=49684 and the >> explanation given there just eludes me as to what C++17 is doing, > > [snip] > > Aren't consts ignored in function parameters? Why are consts ignored in function parameters ? Is not void f(int const) different from void f(int) ? In one the argument passed can not be changed and in the other it can. How can they be the same ? > Then the parameter is not > const and you have a mismatch. Can't you use different parameter types > and use SFINAE by comparing the two after removing const? Thanks ! Maybe I can. But to have to do so in such a simple situation seems very strange. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
I also do not even begin to understand why 'bool (*)(char const)'
becomes 'bool (*)(char)' in any logical world. Clearly a char const is not the same as a char. Who in their right minds would make up a rule that says they are the same, whether in a function declaration or not ? They clearly are not, unless you are out to destroy the notion that top-level consts in function declarations mean anything. That is pretty easy: The function type(!) does NOT include the const of value parameters. My goto for this is godbolt and an easy template test: https://godbolt.org/z/7MvbWb3EW This is why in the function declaration you can omit the const even when you use it in the definition and if you think about it it makes sense: If the function does or does not modify a copied (i.e. by-value) parameter doesn't matter to the caller at all. > > Honestly if this is now C++, something seriously has gone wrong > AFAICS. No doubt I am missing something basic, but this is truly > "Alice in Wonderland" stuff to me. OK, I have had my rant. In what I > was working on I will just specify that T as a top-level const is > disallowed. My design can get by on that, rather than come up with > some tortured code that allows T as a top-level const in the sort of > signature above which works in both C++14 and C++17 on up. In short the takeaway here is: Function value parameters in function signatures are never const. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
On 24.03.21 14:46, Edward Diener via Boost wrote:
> Why are consts ignored in function parameters ? Is not > void f(int const) different from void f(int) ? In one the argument > passed can not be changed and in the other it can. How can they be the > same ? That's an implementation detail of the function f that doesn't (and shouldn't) affect the interface, and the type of f is part of its interface. Let's say that I write a function like this: void countdown(int start_val) { while (start_val >= 0) { std::cout << start_val << "\n" << std::flush; --start_val; } } Later I realize that changing the value of the start_val parameter is confusing, so I rewrite the function like this: void countdown(int const start_val) { for (int val = start_val; val >= 0; --val) { std::cout << val << "\n" << std::flush; } } I am (and should be) allowed to make this change without affecting any users of my function because it is purely an implementation change. -- Rainer Deyke ([hidden email]) _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
On 2021-03-24 at 14:46, Edward Diener via Boost wrote:
> On 3/24/2021 12:42 AM, Felipe Magno de Almeida via Boost wrote: >> On Tue, Mar 23, 2021 at 5:13 PM Edward Diener via Boost >> <[hidden email]> wrote: >> >> Hello Edward, >> >>> I apologize for this non-Boost related post, but I ran into what I >>> thought was a C++17 bug in clang ( also in vc++14.2 C++17 ), whose >>> explanation to me of why it is not a bug really sounds like the >>> non-logic of "Alice in Wonderland". >> >> [snip] >> >>> My bug >>> report is at https://bugs.llvm.org/show_bug.cgi?id=49684 and the >>> explanation given there just eludes me as to what C++17 is doing, >> >> [snip] >> >> Aren't consts ignored in function parameters? > > Why are consts ignored in function parameters ? Is not > void f(int const) different from void f(int) ? In one the argument > passed can not be changed and in the other it can. How can they be the > same ? > As a caller of the function, you cannot tell the difference. So why should they be different? :-) _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
On 2021-03-24 14:46, Edward Diener via Boost wrote:
> Why are consts ignored in function parameters ? Is not > void f(int const) different from void f(int) ? In one the argument > passed can not be changed and in the other it can. How can they be the > same ? The standard states in [dcl.fct]/5 that "After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type." >> Then the parameter is not >> const and you have a mismatch. Can't you use different parameter types >> and use SFINAE by comparing the two after removing const? > > Thanks ! Maybe I can. But to have to do so in such a simple situation > seems very strange. You can use C++20 std::type_identity (or roll your own) to prevent the second T from being deduced. In Richard Smith's example: template<class T, bool (*F)(std::type_identity_t<T>), int> struct X; template<class T, bool (*F)(std::type_identity_t<T>)> struct X<T, F, 0> {}; X<char const, nullptr, 0> x; _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
On 3/24/21 5:45 PM, Bjorn Reese via Boost wrote:
> > You can use C++20 std::type_identity (or roll your own) to prevent the > second T from being deduced. In Richard Smith's example: > > template<class T, bool (*F)(std::type_identity_t<T>), int> struct X; > template<class T, bool (*F)(std::type_identity_t<T>)> struct X<T, F, 0> {}; > X<char const, nullptr, 0> x; As I commented in the clang bug, I don't think you should have to do this. There is only one T this template, and it is explicitly specified at the point of template instantiation, so there's nothing to deduce. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
Am 24.03.2021 um 14:38 schrieb Edward Diener via Boost:
> On 3/24/2021 4:41 AM, Daniela Engert via Boost wrote: >> Am 23.03.2021 um 21:13 schrieb Edward Diener via Boost: >>> I apologize for this non-Boost related post, but I ran into what I >>> thought was a C++17 bug in clang ( also in vc++14.2 C++17 )... >> >> In a template of form >> >> template<class T, bool (*)(T)> whatever >> >> up until C++14, the function argument type in the non-type template >> parameter was never looked at in the deduction of type T because NTTPs >> weren't deemed dependent on placeholder types in their function >> arguments. Beginning with C++17, they are. Therefore you may get >> conflicting type deduction because the second, additional deduction path >> from the function argument type in the NTTP will never deduce a >> top-level cv-qualified T in case of non-reference-like arguments. But >> the first, formerly only deduction path, may. And therein lies the >> conflict in your example where T = const char in the first path and T = >> char is in the second. >> >> Well, at least this is my understanding of P0172. > > I appreciate your explanation, and the following is not directed at > you personally: > > What is there to deduce ? first template argument. The type of the second template argument needs to be deduced. And since it is type-dependent on the function argument it implies a deduction of type T as well. This is the dichotomy between the old order and the new one. > If I specify whatever<char const,nullptr> then T is 'char const'. It's > right there in my instantiation. Making it impossible in this simple > situation to specify the T type when it is a top-level const type can > not be C++ in any logical sense. I also do not even begin to > understand why 'bool (*)(char const)' becomes 'bool (*)(char)' in any > logical world. The declared type is 'bool (*)(char)' in both cases, cv-qualification isn't considered here. This semantic property of function parameters has meaning only within function block scope (or function parameter scope, too? I need to check). And therefore T is deduced to 'char'. > Clearly a char const is not the same as a char. Who in their right > minds would make up a rule that says they are the same, whether in a > function declaration or not ? They clearly are not, unless you are out > to destroy the notion that top-level consts in function declarations > mean anything. > I think this rule exists since the inception of C++. Ciao Dani > Honestly if this is now C++, something seriously has gone wrong > AFAICS. No doubt I am missing something basic, but this is truly > "Alice in Wonderland" stuff to me. OK, I have had my rant. In what I > was working on I will just specify that T as a top-level const is > disallowed. My design can get by on that, rather than come up with > some tortured code that allows T as a top-level const in the sort of > signature above which works in both C++14 and C++17 on up. > > > _______________________________________________ > Unsubscribe & other changes: > http://lists.boost.org/mailman/listinfo.cgi/boost -- PGP/GPG: 2CCB 3ECB 0954 5CD3 B0DB 6AA0 BA03 56A1 2C4638C5 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
In reply to this post by Boost - Dev mailing list
Alexander Grund via Boost said: (by the date of Wed, 24 Mar 2021 14:49:51 +0100)
> In short the takeaway here is: Function value parameters in function > signatures are never const. Just to make clear: value parameters are not reference parameters. const references are recognized. (the most useful argument types for a function :) Janek Kozicki _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
Free forum by Nabble | Edit this page |