digitalmars.D - Bug: Importing but not linking doesn't create module constructors
- Brad Beveridge (37/37) Aug 21 2004 Hi all, I think I have found a slight bug. If I have a wrapper d file t...
- Walter (8/43) Aug 22 2004 that
- Brad Beveridge (9/60) Aug 22 2004 That makes sense, but doesn't it also make sense that when you import a
- Regan Heath (9/72) Aug 22 2004 No, the static constructor is presumably to initialise things in the
- Brad Beveridge (23/100) Aug 22 2004 I was trying to say that by importing a module you are implicitly making
- Regan Heath (43/151) Aug 23 2004 Ahh.. I see, I don't think that statement is true, by saying import foo,...
- brad.beveridge somewhere.co (11/76) Aug 23 2004 OK - now what happens when I use symbols from wrap.d, ie - call function...
-
Regan Heath
(18/33)
Aug 23 2004
On Tue, 24 Aug 2004 00:18:03 +0000 (UTC),
- rad.beveridge somewhere.co (11/40) Aug 23 2004 Everything compiles and links (and generally runs) fine, except that the...
- Regan Heath (41/73) Aug 23 2004 There is definately a bug in it.
Hi all, I think I have found a slight bug. If I have a wrapper d file that simply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the link error that I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that may do critical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux. Cheers Brad
Aug 21 2004
"Brad Beveridge" <brad.beveridge somewhere.com> wrote in message news:cg975q$2uoc$1 digitaldaemon.com...Hi all, I think I have found a slight bug. If I have a wrapper d filethatsimply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the linkerrorthat I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that maydocritical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux.Importing a module is not enough to get it linked in, you must actually reference something in it. It must be that way, because that's the only way to generate extern references to data in D.
Aug 22 2004
Walter wrote:"Brad Beveridge" <brad.beveridge somewhere.com> wrote in message news:cg975q$2uoc$1 digitaldaemon.com...That makes sense, but doesn't it also make sense that when you import a module, it should require the static constructor for that module - if it has one - to be resolved? I think it is inconsistant that having other static module constructors requries imported module constructors to be resolved, but if no modules have static constructors then the imports don't need to be linked. Thoughts? Cheers BradHi all, I think I have found a slight bug. If I have a wrapper d filethatsimply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the linkerrorthat I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that maydocritical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux.Importing a module is not enough to get it linked in, you must actually reference something in it. It must be that way, because that's the only way to generate extern references to data in D.
Aug 22 2004
On Sun, 22 Aug 2004 20:46:26 +1200, Brad Beveridge <brad.beveridge somewhere.com> wrote:Walter wrote:No, the static constructor is presumably to initialise things in the module, if the program does not refer to anything in the module, why initialise it?"Brad Beveridge" <brad.beveridge somewhere.com> wrote in message news:cg975q$2uoc$1 digitaldaemon.com...That makes sense, but doesn't it also make sense that when you import a module, it should require the static constructor for that module - if it has one - to be resolved?Hi all, I think I have found a slight bug. If I have a wrapper d filethatsimply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the linkerrorthat I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that maydocritical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux.Importing a module is not enough to get it linked in, you must actually reference something in it. It must be that way, because that's the only way to generate extern references to data in D.I think it is inconsistant that having other static module constructors requries imported module constructors to be resolved, but if no modules have static constructors then the imports don't need to be linked. Thoughts?I don't understand this last paragraph, pls explain... Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 22 2004
Regan Heath wrote:On Sun, 22 Aug 2004 20:46:26 +1200, Brad Beveridge <brad.beveridge somewhere.com> wrote:I was trying to say that by importing a module you are implicitly making reference to the static constructor. If that statement is true (which I don't know) then the linker should require that the imported module be linked. At the moment it is valid to import a module & use functions from it - ie this is how you wrap a library. Now, what happens if that module also does some important library setup in a static constructor? Well, if you don't link the wrapper then that static constructor will not get called, and the linker will not complain. The inconsistancy arises in the following case: 1. I have the two files (code above), the wrapper exports a static module constructor but since I don't link it doesn't get called. * I think this is the first bug, if you import a module then that module's constructor should be resolved. 2. If I add a static constructor to one of my other modules (uncomment version=broken), THEN the imported (but not linked) wrap module's constructor is required and the linker does actually complain about not resolving the symbol. I think that the behaviour described in 2 is correct, except that you shouldn't need a module ctor in your own modules to force wrap's ctor to come into play. Cheers BradWalter wrote:No, the static constructor is presumably to initialise things in the module, if the program does not refer to anything in the module, why initialise it?"Brad Beveridge" <brad.beveridge somewhere.com> wrote in message news:cg975q$2uoc$1 digitaldaemon.com...That makes sense, but doesn't it also make sense that when you import a module, it should require the static constructor for that module - if it has one - to be resolved?Hi all, I think I have found a slight bug. If I have a wrapper d filethatsimply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the linkerrorthat I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that maydocritical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux.Importing a module is not enough to get it linked in, you must actually reference something in it. It must be that way, because that's the only way to generate extern references to data in D.I think it is inconsistant that having other static module constructors requries imported module constructors to be resolved, but if no modules have static constructors then the imports don't need to be linked. Thoughts?I don't understand this last paragraph, pls explain... Regan
Aug 22 2004
On Mon, 23 Aug 2004 17:39:07 +1200, Brad Beveridge <brad.beveridge somewhere.com> wrote:Regan Heath wrote:Ahh.. I see, I don't think that statement is true, by saying import foo, all you're saying is use foo for lookup name resolution, you're not causing any symbols to be imported, including the static constructor. When you use foo.bar you're importing the bar symbol, and thus the foo module, and thus the static constructor.On Sun, 22 Aug 2004 20:46:26 +1200, Brad Beveridge <brad.beveridge somewhere.com> wrote:I was trying to say that by importing a module you are implicitly making reference to the static constructor. If that statement is true (which I don't know) then the linker should require that the imported module be linked.Walter wrote:No, the static constructor is presumably to initialise things in the module, if the program does not refer to anything in the module, why initialise it?"Brad Beveridge" <brad.beveridge somewhere.com> wrote in message news:cg975q$2uoc$1 digitaldaemon.com...That makes sense, but doesn't it also make sense that when you import a module, it should require the static constructor for that module - if it has one - to be resolved?Hi all, I think I have found a slight bug. If I have a wrapper d filethatsimply wraps some C functions, but also has a static module constructor - ie --- file wrap.d --- static this() { printf("Wrap ctor\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char [][]a) { return 0; } Right - if I compile main.d and don't link it with wrap.o then there is no problems, and no output. I think that this is wrong, I should get an unresolved symbol for the wrap module's static constructor. If I compile main.d with a static constructor, then there is the linkerrorthat I describe above. If I link wrap.o with main.o then everything is correct as expected. I think that this is a bug because you can import wrapper files that maydocritical setup in their static constructor. If you are in a C frame of mind & think of the wrap.d file as a header file, and don't actually link wrap.o - and you have no static constructors of your own - then the imported file's static constructor will not get linked or called - and the linker doesn't complain. I am using DMD 0.100 on linux.Importing a module is not enough to get it linked in, you must actually reference something in it. It must be that way, because that's the only way to generate extern references to data in D.I think it is inconsistant that having other static module constructors requries imported module constructors to be resolved, but if no modules have static constructors then the imports don't need to be linked. Thoughts?I don't understand this last paragraph, pls explain... ReganAt the moment it is valid to import a module & use functions from it - ie this is how you wrap a library. Now, what happens if that module also does some important library setup in a static constructor? Well, if you don't link the wrapper then that static constructor will not get called, and the linker will not complain. The inconsistancy arises in the following case: 1. I have the two files (code above), the wrapper exports a static module constructor but since I don't link it doesn't get called.It doesn't get called because you're not using anything from the wrap module. Try this code: --- file wrap.d --- static this() { printf("Wrap ctor\n"); } void fooBar() { printf("fooBar called\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char[][] a) //modified this from 'char [][]a' <- this is c style :) { fooBar(); return 0; }* I think this is the first bug, if you import a module then that module's constructor should be resolved.I think it's working correctly (assuming my code above does what I think it does) in that if you do not use something from the module, it does not get initialized.2. If I add a static constructor to one of my other modules (uncomment version=broken), THEN the imported (but not linked) wrap module's constructor is required and the linker does actually complain about not resolving the symbol. I think that the behaviour described in 2 is correct, except that you shouldn't need a module ctor in your own modules to force wrap's ctor to come into play.dependency on wrap.d so it's a bug to require it. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 23 2004
<SNIP>OK - now what happens when I use symbols from wrap.d, ie - call functions - but wrap.d is simply defining C functions that get linked from a regular C file? The linker is resolved for those functions and no static constructor gets called. Imagine the case where you wrap a C library, and have a static module constructor that you intend to get called that should setup the library. Currently it is valid to import that wrapper & unknowingly not call the static module constuctor - which I am sure is at best a subtle bug. If you are curious why I am worrying about this - the SDL.d file does exactly the above, wraps a C header & has a module ctor to help startup the library. BradI was trying to say that by importing a module you are implicitly making reference to the static constructor. If that statement is true (which I don't know) then the linker should require that the imported module be linked.Ahh.. I see, I don't think that statement is true, by saying import foo, all you're saying is use foo for lookup name resolution, you're not causing any symbols to be imported, including the static constructor. When you use foo.bar you're importing the bar symbol, and thus the foo module, and thus the static constructor.At the moment it is valid to import a module & use functions from it - ie this is how you wrap a library. Now, what happens if that module also does some important library setup in a static constructor? Well, if you don't link the wrapper then that static constructor will not get called, and the linker will not complain. The inconsistancy arises in the following case: 1. I have the two files (code above), the wrapper exports a static module constructor but since I don't link it doesn't get called.It doesn't get called because you're not using anything from the wrap module. Try this code: --- file wrap.d --- static this() { printf("Wrap ctor\n"); } void fooBar() { printf("fooBar called\n"); } -- file main.d -- import wrap; //version=broken; version(broken) { static this() { printf("ctorTest\n"); } } int main(char[][] a) //modified this from 'char [][]a' <- this is c style :) { fooBar(); return 0; }* I think this is the first bug, if you import a module then that module's constructor should be resolved.I think it's working correctly (assuming my code above does what I think it does) in that if you do not use something from the module, it does not get initialized.2. If I add a static constructor to one of my other modules (uncomment version=broken), THEN the imported (but not linked) wrap module's constructor is required and the linker does actually complain about not resolving the symbol. I think that the behaviour described in 2 is correct, except that you shouldn't need a module ctor in your own modules to force wrap's ctor to come into play.dependency on wrap.d so it's a bug to require it. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 23 2004
On Tue, 24 Aug 2004 00:18:03 +0000 (UTC), <brad.beveridge somewhere.co> wrote: <snip>OK - now what happens when I use symbols from wrap.d, ie - call functions - but wrap.d is simply defining C functions that get linked from a regular C file?I don't know. What happens?The linker is resolved for those functions and no static constructor gets called. Imagine the case where you wrap a C library, and have a static module constructor that you intend to get called that should setup the library. Currently it is valid to import that wrapper & unknowingly not call the static module constuctor - which I am sure is at best a subtle bug.So you're saying that in the above described example it does in fact link but fails to compile and/or execute the static ctor. I agree it is definately a bug, but, the bug could be one of two things, either: - it should call the static ctor in this case. - the static ctor in this case should be illegal.If you are curious why I am worrying about this - the SDL.d file does exactly the above, wraps a C header & has a module ctor to help startup the library.What does the ctor do? Basically I want to know why it's in a static ctor in that particular file and not somewhere else. This will determine exactly what the bug is, once we have that worked out we can post a concise yet complete code segment that reproduces the bug in the digitalmars.d.bugs NG. :) Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 23 2004
<snip>Everything compiles and links (and generally runs) fine, except that the static constructor in wrap.d never gets compiled or linked. I believe that importing a module should imply "I want this module's constructor to get called", and it is not that case right now.OK - now what happens when I use symbols from wrap.d, ie - call functions - but wrap.d is simply defining C functions that get linked from a regular C file?I don't know. What happens?Exactly.The linker is resolved for those functions and no static constructor gets called. Imagine the case where you wrap a C library, and have a static module constructor that you intend to get called that should setup the library. Currently it is valid to import that wrapper & unknowingly not call the static module constuctor - which I am sure is at best a subtle bug.So you're saying that in the above described example it does in fact link but fails to compile and/or execute the static ctor.I agree it is definately a bug, but, the bug could be one of two things, either: - it should call the static ctor in this case. - the static ctor in this case should be illegal.In the SDL case it calls (I think) SDL_Init(SDL_PARACHUTE). But for any given library that you wrap, you may want to have library specific initialisation in that wrapper module's constructor. I don't think that I have been very clear in my description of this bug, if someone could rephrase it..... :) BradIf you are curious why I am worrying about this - the SDL.d file does exactly the above, wraps a C header & has a module ctor to help startup the library.What does the ctor do? Basically I want to know why it's in a static ctor in that particular file and not somewhere else. This will determine exactly what the bug is, once we have that worked out we can post a concise yet complete code segment that reproduces the bug in the digitalmars.d.bugs NG. :)
Aug 23 2004
On Tue, 24 Aug 2004 02:12:39 +0000 (UTC), <rad.beveridge somewhere.co> wrote:There is definately a bug in it.Everything compiles and links (and generally runs) fine, except that the static constructor in wrap.d never gets compiled or linked.OK - now what happens when I use symbols from wrap.d, ie - call functions - but wrap.d is simply defining C functions that get linked from a regular C file?I don't know. What happens?I believe that importing a module should imply "I want this module's constructor to get called", and it is not that case right now.I don't agree with that idea. An import statement simply tells the compiler where to look for name resolution, it does not import any symbols, the use of a symbol imports it. Consider this: --wrap.d-- static this() { SDL_Init(SDL_PARACHUTE) } extern (C) { SDL_Thing(); } --main.d-- void main() { } now, as main.d does not call SDL_Thing(); there is no point in doing the SDL_Init call, basically the module isn't being used, so why link it in. The bug, as I see it, is: due to the symbols being defined as extern (C) the linker does not realise they're in use and are part of the module, so does not link the static constructor. I reckon you re-post this to the digitalmars.D.bugs NG, make sure you include the call to the extern C declared function in the module with the static this which is being ignored. In the meantime you could move the static constructor from where it is and put it in your main.d file. One could argue that was where it belonged anyway. If on the other hand you we're wrapping a class interface round it then it would likely belong where it is, at the same time you wouldn't have this bug (I reckon) as you'd be using a D class from that module and the linker would notice and compile/execute the static constructor.I agree. I was just checking.In the SDL case it calls (I think) SDL_Init(SDL_PARACHUTE). But for any given library that you wrap, you may want to have library specific initialisation in that wrapper module's constructor.If you are curious why I am worrying about this - the SDL.d file does exactly the above, wraps a C header & has a module ctor to help startup the library.What does the ctor do? Basically I want to know why it's in a static ctor in that particular file and not somewhere else. This will determine exactly what the bug is, once we have that worked out we can post a concise yet complete code segment that reproduces the bug in the digitalmars.d.bugs NG. :)I don't think that I have been very clear in my description of this bug, if someone could rephrase it..... :)I understand what you're saying, I know what you want to happen, I know what is happening, I'm just thoughroughly exploring the entire thing. It's not my job, I know, I just can't help it, besides, if the result is that we have a concise bug report that takes Walter less time to fix, everyone is happy. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 23 2004