May 11, 2017
On Thu, May 11, 2017 at 07:46:24PM -0400, Steven Schveighoffer via Digitalmars-d wrote: [...]
> But this still doesn't mean that *all* bool conversions are value based. In at least the struct and class cases, more than just the bits are checked.
[...]

Wait, what?  You can use a *struct* as a bool condition?!

I tried this:

	import std.stdio;
	struct S {}
	void main() {
		S s;
		if (s) { writeln("WAT"); }
	}

But the compiler (rightly) said:

	test.d(5): Error: expression s of type S does not have a boolean value

Or were you talking about structs that define opCast!bool? (In which case it's certainly intentional and doesn't pose a problem.)

I can see classes being usable in conditions, though, since they're essentially pointers hiding behind an abstraction. Still, it doesn't quite sit right with me. For example:

	class C { }
	class D { bool opCast(T : bool)() { return false; } }
	void main() {
		C c;
		D d = new D;

		if (!c) { ... }		// OK, expected semantics
		if (!d) { ... }		// *** What happens here?
	}

Whereas had the last two lines been written:

		if (c is null) { ... }
		if (d is null) { ... }

the intent would be much clearer. (And of course, d would be usable without "is null" if you actually intended to invoke opCast!bool.)


T

-- 
In a world without fences, who needs Windows and Gates? -- Christian Surchi
May 12, 2017
On 5/11/17 7:52 PM, H. S. Teoh via Digitalmars-d wrote:
> On Thu, May 11, 2017 at 07:46:24PM -0400, Steven Schveighoffer via Digitalmars-d wrote:
> [...]
>> But this still doesn't mean that *all* bool conversions are value
>> based. In at least the struct and class cases, more than just the bits
>> are checked.
> [...]
>
> Wait, what?  You can use a *struct* as a bool condition?!
>
> I tried this:
>
> 	import std.stdio;
> 	struct S {}
> 	void main() {
> 		S s;
> 		if (s) { writeln("WAT"); }
> 	}
>
> But the compiler (rightly) said:
>
> 	test.d(5): Error: expression s of type S does not have a boolean value
>
> Or were you talking about structs that define opCast!bool? (In which
> case it's certainly intentional and doesn't pose a problem.)

Yes, I was talking about that.

> I can see classes being usable in conditions, though, since they're
> essentially pointers hiding behind an abstraction. Still, it doesn't
> quite sit right with me. For example:
>
> 	class C { }
> 	class D { bool opCast(T : bool)() { return false; } }
> 	void main() {
> 		C c;
> 		D d = new D;
>
> 		if (!c) { ... }		// OK, expected semantics
> 		if (!d) { ... }		// *** What happens here?
> 	}

I have totally misremembered the thing of classes and invariants. So my statement on that is wrong.

It's when you *assert* a class instance that the invariant is checked, not when used in an if condition.

Testing out your question, the opCast to bool doesn't apply for classes. Just the reference is checked against null. You have to write cast(bool)d to trigger the opCast.

So classes are just like pointers. Really only structs offer some semblance of control for use in if statements.

-Steve
1 2 3
Next ›   Last »