Re: Is it safe to use 'is' to compare types?
On Thursday, 10 March 2016 at 02:14:19 UTC, H. S. Teoh wrote: On Thu, Mar 10, 2016 at 01:33:41AM +, Yuxuan Shui via Digitalmars-d-learn wrote: [...] You can't rely on invoking the compiler to link these objects, because if you're using shared libraries, it will be the OS's dynamic linker that will get invoked to resolve the references, and different versions of shared libraries may have a different set of TypeInfo's, and the compiler may not be able to generate the required TypeInfo's. A better way is to use the OS linker's "weak symbol" feature, where a symbol is allowed to be defined multiple times (with identical content), and the linker (both dynamic and static) will choose the first definition that it finds. However weak symbol overriding is deprecated on Linux (see ld.so(8)). If we want to go all out to solve this problem, there are clearly solutions. But for now there doesn't seem to be enough benefit to justify the amount of work needed. T
Re: Is it safe to use 'is' to compare types?
On Thu, Mar 10, 2016 at 01:33:41AM +, Yuxuan Shui via Digitalmars-d-learn wrote: > On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote: > >On 03/09/2016 07:05 AM, Yuxuan Shui wrote: > > > >> Can we left TypeInfo symbol undefined in the shared libraries? i.e. > >> D compiler will strip out TypeInfo definition when creating .so. > >> (Alternatively, we can have TypeInfo always undefined in .o, and > >> generate them in linking stage only when creating executables) > > > >That would require a linker that's aware of D but as far as I know, > >all system languages use the system linker. > > > >Ali > > Hmm, how about this: > > During compilation, D generate undefined TypeInfo symbols, but it also > embed type information in the object file (like what Rust does). And > then, when dmd/ldc/gdc/whatever is called for linking executables, it > will scan object files and generate another object file containing the > TypeInfos, and link them together with the system linker. If the > compiler is called for linking shared libraries, it doesn't. You can't rely on invoking the compiler to link these objects, because if you're using shared libraries, it will be the OS's dynamic linker that will get invoked to resolve the references, and different versions of shared libraries may have a different set of TypeInfo's, and the compiler may not be able to generate the required TypeInfo's. A better way is to use the OS linker's "weak symbol" feature, where a symbol is allowed to be defined multiple times (with identical content), and the linker (both dynamic and static) will choose the first definition that it finds. T -- Маленькие детки - маленькие бедки.
Re: Is it safe to use 'is' to compare types?
On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote: On 03/09/2016 07:05 AM, Yuxuan Shui wrote: > Can we left TypeInfo symbol undefined in the shared libraries? i.e. D > compiler will strip out TypeInfo definition when creating .so. > (Alternatively, we can have TypeInfo always undefined in .o, and > generate them in linking stage only when creating executables) That would require a linker that's aware of D but as far as I know, all system languages use the system linker. Ali Hmm, how about this: During compilation, D generate undefined TypeInfo symbols, but it also embed type information in the object file (like what Rust does). And then, when dmd/ldc/gdc/whatever is called for linking executables, it will scan object files and generate another object file containing the TypeInfos, and link them together with the system linker. If the compiler is called for linking shared libraries, it doesn't.
Re: Is it safe to use 'is' to compare types?
On 03/09/2016 07:05 AM, Yuxuan Shui wrote: > Can we left TypeInfo symbol undefined in the shared libraries? i.e. D > compiler will strip out TypeInfo definition when creating .so. > (Alternatively, we can have TypeInfo always undefined in .o, and > generate them in linking stage only when creating executables) That would require a linker that's aware of D but as far as I know, all system languages use the system linker. Ali
Re: Is it safe to use 'is' to compare types?
On Tuesday, 8 March 2016 at 23:13:32 UTC, Anon wrote: On Tuesday, 8 March 2016 at 20:26:04 UTC, Yuxuan Shui wrote: [...] [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.] [...] Can we left TypeInfo symbol undefined in the shared libraries? i.e. D compiler will strip out TypeInfo definition when creating .so. (Alternatively, we can have TypeInfo always undefined in .o, and generate them in linking stage only when creating executables)
Re: Is it safe to use 'is' to compare types?
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___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.
Re: Is it safe to use 'is' to compare types?
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___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
Re: Is it safe to use 'is' to compare types?
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___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?
Re: Is it safe to use 'is' to compare types?
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___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
Re: Is it safe to use 'is' to compare types?
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___initZ symbol?
Re: Is it safe to use 'is' to compare types?
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
Re: Is it safe to use 'is' to compare types?
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
Re: Is it safe to use 'is' to compare types?
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.
Re: Is it safe to use 'is' to compare types?
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.
Is it safe to use 'is' to compare types?
Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?