Opened 6 years ago
Last modified 6 years ago
#91 new defect
Assignment to bool, not a boolean context
Reported by: | Thierry Delisle | Owned by: | |
---|---|---|---|
Priority: | minor | Component: | cfa-cc |
Version: | 1.0 | Keywords: | |
Cc: |
Description
Assignment to bool and condition evaluation behave differently :
#include <stdbool.h> struct fred {}; bool ?!=?(const fred & this, zero_t) { return true; } void foo() { fred f; if(f) {} bool test = f; }
Change History (5)
comment:1 Changed 6 years ago by
comment:2 Changed 6 years ago by
Thierry says we also want a couple more operators:
forall(dtype T | { int ?!=?(const T&, zero_t); }) int !?(const T& x) { return !(x != 0); } forall(dtype T | { int ?!=?(const T&, zero_t); }) int ?==?(const T& x, zero_t ) { return !(x != 0); }
comment:3 Changed 6 years ago by
An unintended consequence of this is that by adding this constructor, _Bool
becomes a "managed type" (and transitively, any struct including bool becomes managed as well). The only thing this seems to break in the test suite is the initialization of kernelTLS
in libcfa/concurrency/kernel.c
(easily fixed with an @=
initializer), but the implications of bool being "managed" seem wrong.
Options:
- Status quo; do nothing, reject this enhancement request
- Merge the suggested change above, accept
_Bool
as a managed type - Change the definition of managed type somehow to exclude this case (not sure if that's possible)
- If we ever put in user-defined implicit conversions, implement the above something like this:
forall(dtype T | { int ?!=? ( const T&, zero_t ); } ) void ?{safe} ( _Bool& b, const T& x ) { b = (x != 0); }
comment:4 Changed 6 years ago by
With respect to option 3, I already ignore intrinsic and autogenerated constructors in the definition of managed types. It would be easy to expand the definition to also ignore builtins. The trick is that with the current setup, if a type is not managed I don't even try to implicitly construct it, so you wouldn't get the desired behavior from the new constructors.
It might be possible to do something in between. For example, builtins constructors change a type to managed, but that managed status does not propagate to other types. I don't love the way this complicated the definition though.
comment:5 Changed 6 years ago by
I don't love that complication either.
I lean toward option 4, with a suggested mitigation in the meantime of bool test = f != 0;
(for the original code snippet).
I think maybe the way to handle this is with another "default" function in builtins.c (much like the ones that implement ++ and -- in terms of +=), something like the following: