Jump to page: 1 2
Thread overview
Is it safe to use 'is' to compare types?
Mar 03, 2016
Yuxuan Shui
Mar 03, 2016
Adam D. Ruppe
Mar 03, 2016
Yuxuan Shui
Mar 04, 2016
Yuxuan Shui
Mar 04, 2016
Yuxuan Shui
Mar 08, 2016
Yuxuan Shui
Mar 08, 2016
Anon
Mar 09, 2016
Yuxuan Shui
Mar 09, 2016
Ali Çehreli
Mar 10, 2016
Yuxuan Shui
Mar 10, 2016
H. S. Teoh
Mar 10, 2016
Yuxuan Shui
March 03, 2016
Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?
March 03, 2016
On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
> Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?

No. Indeed, opEquals on TypeInfo just calls is itself.
March 03, 2016
On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:
> On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
>> Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?
>
> No. Indeed, opEquals on TypeInfo just calls is itself.

But opEquals also has extra comparison:

        auto ti = cast(const TypeInfo)o;
        return ti && this.toString() == ti.toString();

This makes me feel they are not the same.
March 04, 2016
On Thursday, 3 March 2016 at 23:58:39 UTC, Yuxuan Shui wrote:
> On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:
>> On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
>>> Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?
>>
>> No. Indeed, opEquals on TypeInfo just calls is itself.
>
> But opEquals also has extra comparison:
>
>         auto ti = cast(const TypeInfo)o;
>         return ti && this.toString() == ti.toString();
>
> This makes me feel they are not the same.

Oh, I get it. 'a is b' works for the results of typeid(). But not for duplicates of TypeInfo.

For example:

	import std.stdio;
	A a, b;
	auto x = typeid(a), y = typeid(b);
	writeln(x is y);
	auto xz = ((cast(ubyte *)x)[0..typeof(x).classinfo.init.length]).dup; //Evil
	auto z = cast(typeof(x))(cast(void *)xz);
	writeln(x is z); //false
	writeln(x == z); //true


March 04, 2016
On 3/3/16 6:58 PM, Yuxuan Shui wrote:
> On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:
>> On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
>>> Will typeid(a) is typeid(b) yield different results than typeid(a) ==
>>> typeid(b)?
>>
>> No. Indeed, opEquals on TypeInfo just calls is itself.
>
> But opEquals also has extra comparison:
>
>          auto ti = cast(const TypeInfo)o;
>          return ti && this.toString() == ti.toString();
>
> This makes me feel they are not the same.

In some cases, for instance using DLLs, the TypeInfo for an object allocated in one way may be identical, but be a different instance from the TypeInfo allocated in another way. This is why the string comparison occurs.

Note that comparing ANY object will first check if they are the same instance before calling any functions (this is in object.opEquals)

-Steve
March 04, 2016
On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote:
> On 3/3/16 6:58 PM, Yuxuan Shui wrote:
>> On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:
>>> On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
>>>> Will typeid(a) is typeid(b) yield different results than typeid(a) ==
>>>> typeid(b)?
>>>
>>> No. Indeed, opEquals on TypeInfo just calls is itself.
>>
>> But opEquals also has extra comparison:
>>
>>          auto ti = cast(const TypeInfo)o;
>>          return ti && this.toString() == ti.toString();
>>
>> This makes me feel they are not the same.
>
> In some cases, for instance using DLLs, the TypeInfo for an object allocated in one way may be identical, but be a different instance from the TypeInfo allocated in another way. This is why the string comparison occurs.
>
> Note that comparing ANY object will first check if they are the same instance before calling any functions (this is in object.opEquals)
>
> -Steve

Thanks for answering. But I still don't understand why TypeInfo would need to be allocated. Aren't typeid() just returning references to the __DxxTypeInfo_xxxx__initZ symbol?
March 07, 2016
On 3/4/16 4:30 PM, Yuxuan Shui wrote:
> On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote:
>> On 3/3/16 6:58 PM, Yuxuan Shui wrote:
>>> On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:
>>>> On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
>>>>> Will typeid(a) is typeid(b) yield different results than typeid(a) ==
>>>>> typeid(b)?
>>>>
>>>> No. Indeed, opEquals on TypeInfo just calls is itself.
>>>
>>> But opEquals also has extra comparison:
>>>
>>>          auto ti = cast(const TypeInfo)o;
>>>          return ti && this.toString() == ti.toString();
>>>
>>> This makes me feel they are not the same.
>>
>> In some cases, for instance using DLLs, the TypeInfo for an object
>> allocated in one way may be identical, but be a different instance
>> from the TypeInfo allocated in another way. This is why the string
>> comparison occurs.
>>
>> Note that comparing ANY object will first check if they are the same
>> instance before calling any functions (this is in object.opEquals)
>>
>
> Thanks for answering. But I still don't understand why TypeInfo would
> need to be allocated. Aren't typeid() just returning references to the
> __DxxTypeInfo_xxxx__initZ symbol?

You misunderstood, I meant the typeinfo *for* an allocated object, not that the typeinfo was allocated.

In some cases, 2 different objects allocated from different libraries (usually DLL-land) may reference TypeInfo from different segments, even though the TypeInfo is identical.

-Steve
March 08, 2016
On Monday, 7 March 2016 at 16:13:45 UTC, Steven Schveighoffer wrote:
> On 3/4/16 4:30 PM, Yuxuan Shui wrote:
>> On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote:
>>>[...]
>>
>> Thanks for answering. But I still don't understand why TypeInfo would
>> need to be allocated. Aren't typeid() just returning references to the
>> __DxxTypeInfo_xxxx__initZ symbol?
>
> You misunderstood, I meant the typeinfo *for* an allocated object, not that the typeinfo was allocated.
>
> In some cases, 2 different objects allocated from different libraries (usually DLL-land) may reference TypeInfo from different segments, even though the TypeInfo is identical.
>
> -Steve

Hmm... Does that mean each DLL will have their own TypeInfo symbols for the same type?
March 08, 2016
On 3/8/16 3:26 PM, Yuxuan Shui wrote:
> On Monday, 7 March 2016 at 16:13:45 UTC, Steven Schveighoffer wrote:
>> On 3/4/16 4:30 PM, Yuxuan Shui wrote:
>>> On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote:
>>>> [...]
>>>
>>> Thanks for answering. But I still don't understand why TypeInfo would
>>> need to be allocated. Aren't typeid() just returning references to the
>>> __DxxTypeInfo_xxxx__initZ symbol?
>>
>> You misunderstood, I meant the typeinfo *for* an allocated object, not
>> that the typeinfo was allocated.
>>
>> In some cases, 2 different objects allocated from different libraries
>> (usually DLL-land) may reference TypeInfo from different segments,
>> even though the TypeInfo is identical.
>>
> Hmm... Does that mean each DLL will have their own TypeInfo symbols for
> the same type?

I don't know the exact circumstances. I think the answer is both yes and no, depending on the situation :)

But I know this is the reason for the string comparison.

-Steve
March 08, 2016
On Tuesday, 8 March 2016 at 20:26:04 UTC, Yuxuan Shui wrote:
> On Monday, 7 March 2016 at 16:13:45 UTC, Steven Schveighoffer wrote:
>> On 3/4/16 4:30 PM, Yuxuan Shui wrote:
>>> On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote:
>>>>[...]
>>>
>>> Thanks for answering. But I still don't understand why TypeInfo would
>>> need to be allocated. Aren't typeid() just returning references to the
>>> __DxxTypeInfo_xxxx__initZ symbol?
>>
>> You misunderstood, I meant the typeinfo *for* an allocated object, not that the typeinfo was allocated.
>>
>> In some cases, 2 different objects allocated from different libraries (usually DLL-land) may reference TypeInfo from different segments, even though the TypeInfo is identical.
>>
>> -Steve
>
> Hmm... Does that mean each DLL will have their own TypeInfo symbols for the same type?

[Note: I phrase my answer in terms of Linux shared libraries (*.so) because D doesn't actually have proper Windows DLL support yet. The same would apply to DLLs, it just feels wrong describing functionality that doesn't exist.]

They can, mostly due to templated types. Consider modules `common`, `foo`, and `bar` (all built as shared libraries), and `main` (built as an executable).

module common; // => common.so
struct List(T)
{
    // ...
}

module foo; // => foo.so, links to common.so
import common;

List!int getList()
{
    // ...
}

module bar; // => bar.so, links to common.so
import common

void processList(List!int a)
{
    // ...
}

module main; // => main, links to foo.so, bar.so, and common.so
import foo, bar;

void main()
{
    processList(getList());
}

No part of List!int is instantiated in common, so no part of it is actually present in common.so. Instead, it is instantiated in foo and bar, and thus separate copies of List!int are present in foo.so and bar.so, along with TypeInfo for List!int.

If you were to statically link instead (using .a or .lib files), the linker would keep only one copy of List!int and its TypeInfo, but the linker can't eliminate either of them when dealing with shared libraries.

So, yes, I think the string comparison is needed, as awkward as it may seem in many circumstances.
« First   ‹ Prev
1 2