On 23 September 2016 at 17:11, <rhalb...@gmail.com> wrote:
>>
>> I don't believe it's feasible for a C++ implementation to enable the
>> warning we're talking about by default.
>
>
> Could you explain? I'm not suggesting to warn for implicit conversion at the
> point of call, but only inside the class definition.
I expect that there's a fair amount of non-annotated code that has
such implicit conversion
constructors in it, not to mention implicit conversion operators.
The Facebook program verifier flint (https://code.facebook.com/posts/729709347050548/under-the-hood-building-and-open-sourcing-flint/) encourages that non-explicit single-argument constructors and conversion operators should be marked with /* implicit */ comments (rules 14 and 22).I wonder if there would be Committee support for a proposal for an [[implicit]] attribute. Compilers could be encouraged to warn about missing attribute on non-explicit single argument constructors and conversion operators without such an attribute annotation. Neither gcc nor clang appear to have warnings for this at the moment.
Wouldn't it be better to depricate the explicit keyword in favor of having it by default? That is, replace "explicit" with "implicit".
I have no interest in 0), unless we plan for the 20+ year process.
Adding an attribute to raise warnings essentially forces a keyword on
all constructors, whether implicit or explicit, adding burden on all users
of the language.
I have no interest in 0), unless we plan for the 20+ year process.
Adding an attribute to raise warnings essentially forces a keyword on
all constructors, whether implicit or explicit, adding burden on all users
of the language.
I didn't mean to propose [[implicit]] to suppress warnings for copy/move constructors, inherited constructors or even conversion to base classes.
Only for single argument constructors from / conversions to unrelated types.
So. e.g. std::bitset has implicit constructors from unsigned long and unsigned long long, they can be surprising (especially since the overloaded bit-operators for std::bitset do not have such conversions on their arguments).
Only for single argument constructors from / conversions to unrelated types.And what do you do about things like:struct Foo {Foo(std::string s, int i = 0);template<typename... Ts>Foo(Ts&&...) { /* ... */ }};Do we get warnings for either of those? Both of those? Neither of those?
So. e.g. std::bitset has implicit constructors from unsigned long and unsigned long long, they can be surprising (especially since the overloaded bit-operators for std::bitset do not have such conversions on their arguments).That may be (I don't know the original motivation and I'm not motivated enough to do the archeology),
On Wed, Sep 28, 2016 at 1:00 PM, Rein Halbersma <rhalb...@gmail.com> wrote:I didn't mean to propose [[implicit]] to suppress warnings for copy/move constructors, inherited constructors or even conversion to base classes.Oh, you want a complicated rule.
Only for single argument constructors from / conversions to unrelated types.And what do you do about things like:struct Foo {Foo(std::string s, int i = 0);template<typename... Ts>Foo(Ts&&...) { /* ... */ }};Do we get warnings for either of those? Both of those? Neither of those?
On Wed, Sep 28, 2016 at 9:09 AM, Alisdair Meredith <alis...@me.com> wrote:I have no interest in 0), unless we plan for the 20+ year process.
Adding an attribute to raise warnings essentially forces a keyword on
all constructors, whether implicit or explicit, adding burden on all users
of the language.
+1 to both of these.And personally, I've found making copy constructors explicit to just be troublesome (and I've never experimented with making move constructors explicit because of that), but I assume the people wanting this feature have the opposite experience, or they would have mentioned this, given that copy constructors are the most popular non-explicit single argument constructors.
Foo::Foo(std::string s, int i = 0);
template<typename... Ts>
Foo::Foo(Ts&&...) { /* ... */ }
Is potentially buggy. Do you really want to construct from about *everything*? Such constructors are known to have caused bugs: http://ericniebler.com/2013/08/07/universal-references-and-the-copy-constructo/
They "compete" with copy/move constructors, if not anything else. Nonetheless, it is potentially converting -- will trigger a warning
template<typename... Ts>
Foo::Foo(Ts&&...) { /* ... */ }