Date: Sat, 22 Jul 2023 11:31:28 -0400
On Sat, Jul 22, 2023 at 4:40 AM sasho648 via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> int arr[2];
> bool test = arr;
> bool teststr = "string";
>
>
> Which I came across while having a function like this:
>
> void set_property(const char *name, const char *default_value);
> void set_property_bool(const char*name, bool default_value);
>
> Where I thought the bool one was expecting a string as second argument as
> well and so I wrote:
> set_property_bool("test", "true");
>
> Which compiled fine and even worked until I decided to change it to:
> set_property_bool("test", "false");
>
TBF, that's not a terribly convincing failure mode: obviously `"false"` is
not the same thing as `false` (in C++).
However, I have actually run into this implicit conversion before:
https://quuxplusone.github.io/blog/2020/10/11/overloading-considered-harmful/#here-s-another-example-of-grief
void f(int x, bool b);
void f(int x, std::string s);
... f(42, "some string"); ...
calls f(int, bool), not f(int, string).
However, the original sin in that case was "too much overloading," and the
fix was to give the two different `f`s two different names, just as OP did
with `set_property` and `set_property_bool`.
I think it would be quite reasonable to make pointers (and thus arrays)
only *contextually* convertible to bool.
Contextual conversion is *generally* not done by accident. People have
already pointed out the `assert(x && "hi")` idiom. Another place I have
used it is in macro-expansion, like
#define CHECK(input, out1, out2) do { auto [x,y] = f(input);
ASSERT_STREQ(x, out1 ? out1 : input); ASSERT_STREQ(y, out2 ? out2 : ""); }
while (0)
#define NONE (const char*)nullptr
CHECK("input1", "xyz", NONE);
CHECK("input2", NONE, "xyz");
[...]
However, I personally wouldn't try to change the language here. I'd just
contact your friendly neighborhood compiler vendor and ask them to add a
diagnostic for "non-contextual implicit conversion of pointer to bool"...
if they haven't already done so.
Clang has `-Wstring-conversion` for the `f` example above, where the
pointer comes specifically from a *string literal*.
Clang lacks any warning for *general* non-contextual pointer-to-bool
conversion.
In general, everyone's first instinct (when you find a bug in your code
that a machine could have detected) should be to *add a compiler warning*
that can be enabled or disabled for your specific codebase, not to *change
the semantics of the language* for everyone else in the world.
HTH,
Arthur
std-proposals_at_[hidden]> wrote:
>
> int arr[2];
> bool test = arr;
> bool teststr = "string";
>
>
> Which I came across while having a function like this:
>
> void set_property(const char *name, const char *default_value);
> void set_property_bool(const char*name, bool default_value);
>
> Where I thought the bool one was expecting a string as second argument as
> well and so I wrote:
> set_property_bool("test", "true");
>
> Which compiled fine and even worked until I decided to change it to:
> set_property_bool("test", "false");
>
TBF, that's not a terribly convincing failure mode: obviously `"false"` is
not the same thing as `false` (in C++).
However, I have actually run into this implicit conversion before:
https://quuxplusone.github.io/blog/2020/10/11/overloading-considered-harmful/#here-s-another-example-of-grief
void f(int x, bool b);
void f(int x, std::string s);
... f(42, "some string"); ...
calls f(int, bool), not f(int, string).
However, the original sin in that case was "too much overloading," and the
fix was to give the two different `f`s two different names, just as OP did
with `set_property` and `set_property_bool`.
I think it would be quite reasonable to make pointers (and thus arrays)
only *contextually* convertible to bool.
Contextual conversion is *generally* not done by accident. People have
already pointed out the `assert(x && "hi")` idiom. Another place I have
used it is in macro-expansion, like
#define CHECK(input, out1, out2) do { auto [x,y] = f(input);
ASSERT_STREQ(x, out1 ? out1 : input); ASSERT_STREQ(y, out2 ? out2 : ""); }
while (0)
#define NONE (const char*)nullptr
CHECK("input1", "xyz", NONE);
CHECK("input2", NONE, "xyz");
[...]
However, I personally wouldn't try to change the language here. I'd just
contact your friendly neighborhood compiler vendor and ask them to add a
diagnostic for "non-contextual implicit conversion of pointer to bool"...
if they haven't already done so.
Clang has `-Wstring-conversion` for the `f` example above, where the
pointer comes specifically from a *string literal*.
Clang lacks any warning for *general* non-contextual pointer-to-bool
conversion.
In general, everyone's first instinct (when you find a bug in your code
that a machine could have detected) should be to *add a compiler warning*
that can be enabled or disabled for your specific codebase, not to *change
the semantics of the language* for everyone else in the world.
HTH,
Arthur
Received on 2023-07-22 15:31:41