digitalmars.D.learn - Is it safe to use 'is' to compare types?
- Yuxuan Shui (2/2) Mar 03 2016 Will typeid(a) is typeid(b) yield different results than
- Adam D. Ruppe (2/4) Mar 03 2016 No. Indeed, opEquals on TypeInfo just calls is itself.
- Yuxuan Shui (5/9) Mar 03 2016 But opEquals also has extra comparison:
- Yuxuan Shui (13/23) Mar 03 2016 Oh, I get it. 'a is b' works for the results of typeid(). But not
- Steven Schveighoffer (8/18) Mar 04 2016 In some cases, for instance using DLLs, the TypeInfo for an object
- Yuxuan Shui (5/28) Mar 04 2016 Thanks for answering. But I still don't understand why TypeInfo
- Steven Schveighoffer (7/34) Mar 07 2016 You misunderstood, I meant the typeinfo *for* an allocated object, not
- Yuxuan Shui (4/20) Mar 08 2016 Hmm... Does that mean each DLL will have their own TypeInfo
- Steven Schveighoffer (5/23) Mar 08 2016 I don't know the exact circumstances. I think the answer is both yes and...
- Anon (41/64) Mar 08 2016 [Note: I phrase my answer in terms of Linux shared libraries
- Yuxuan Shui (5/12) Mar 09 2016 Can we left TypeInfo symbol undefined in the shared libraries?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/8) Mar 09 2016 That would require a linker that's aware of D but as far as I know, all
- Yuxuan Shui (9/19) Mar 09 2016 Hmm, how about this:
- H. S. Teoh via Digitalmars-d-learn (13/34) Mar 09 2016 You can't rely on invoking the compiler to link these objects, because
- Yuxuan Shui (6/20) Mar 10 2016 However weak symbol overriding is deprecated on Linux (see
Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?
Mar 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.
Mar 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: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.Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?No. Indeed, opEquals on TypeInfo just calls is itself.
Mar 03 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: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); //trueOn Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote: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.Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?No. Indeed, opEquals on TypeInfo just calls is itself.
Mar 03 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: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) -SteveOn Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote: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.Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?No. Indeed, opEquals on TypeInfo just calls is itself.
Mar 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: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?On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote: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) -SteveOn Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote: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.Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?No. Indeed, opEquals on TypeInfo just calls is itself.
Mar 04 2016
On 3/4/16 4:30 PM, Yuxuan Shui wrote:On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote: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. -SteveOn 3/3/16 6:58 PM, Yuxuan Shui 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?On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote: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)On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote: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.Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?No. Indeed, opEquals on TypeInfo just calls is itself.
Mar 07 2016
On Monday, 7 March 2016 at 16:13:45 UTC, Steven Schveighoffer wrote:On 3/4/16 4:30 PM, Yuxuan Shui wrote:Hmm... Does that mean each DLL will have their own TypeInfo symbols for the same type?On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote: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[...]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?
Mar 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: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. -SteveOn 3/4/16 4:30 PM, Yuxuan Shui wrote:Hmm... Does that mean each DLL will have their own TypeInfo symbols for the same type?On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote: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.[...]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?
Mar 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:[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.On 3/4/16 4:30 PM, Yuxuan Shui wrote:Hmm... Does that mean each DLL will have their own TypeInfo symbols for the same type?On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer wrote: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[...]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?
Mar 08 2016
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: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)[...][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.] [...]
Mar 09 2016
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
Mar 09 2016
On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote:On 03/09/2016 07:05 AM, Yuxuan Shui wrote: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.Can we left TypeInfo symbol undefined in the sharedlibraries? i.e. Dcompiler will strip out TypeInfo definition when creating .so. (Alternatively, we can have TypeInfo always undefined in .o,andgenerate 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
Mar 09 2016
On Thu, Mar 10, 2016 at 01:33:41AM +0000, Yuxuan Shui via Digitalmars-d-learn wrote:On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli 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. T -- Маленькие детки - маленькие бедки.On 03/09/2016 07:05 AM, Yuxuan Shui wrote: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.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
Mar 09 2016
On Thursday, 10 March 2016 at 02:14:19 UTC, H. S. Teoh wrote:On Thu, Mar 10, 2016 at 01:33:41AM +0000, Yuxuan Shui via Digitalmars-d-learn wrote: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.[...]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
Mar 10 2016