digitalmars.D.bugs - [Issue 1830] New: duplicated constants + extern(Windows) = Link error: Previous Definition Different
- d-bugmail puremagic.com (51/51) Feb 12 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
- d-bugmail puremagic.com (4/4) Feb 12 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
- d-bugmail puremagic.com (14/14) Feb 13 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
- d-bugmail puremagic.com (17/17) Feb 13 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
- d-bugmail puremagic.com (19/32) Feb 13 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
- d-bugmail puremagic.com (16/16) Mar 03 2008 http://d.puremagic.com/issues/show_bug.cgi?id=1830
http://d.puremagic.com/issues/show_bug.cgi?id=1830 Summary: duplicated constants + extern(Windows) = Link error: Previous Definition Different Product: D Version: 1.025 Platform: PC OS/Version: Windows Status: NEW Keywords: link-failure Severity: normal Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: wbaxter gmail.com If two modules define the same constants it's usually OK. But if those constants are extern(windows) then they will create linker errors. ---link_main.d--- module link_main; import link_a; import link_b; void main() { } ---link_a.d--- module link_a; extern(Windows): const uint FOO = cast(uint)-1; ---link_b.d--- module link_b; extern(Windows): const uint FOO = cast(uint)-1; --- Build with dmd link_main link_a link_b And you get: """ f:\usr\pkg\d\dmd\bin\..\..\dm\bin\link.exe link_main+link_a+link_b,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved link_b.obj(link_b) Offset 000E0H Record Type 0091 Error 1: Previous Definition Different : _FOO --- errorlevel 1 """ If you remove the extern(Windows) lines, it links fine. This is causing trouble when linking apps that import more than one Windows API wrapper since most of them stick an extern(Windows): at the top of the file, which ends up covering all the constants as well as functions. I'm not even sure if extern(Windows) has meaning for constants like that, but it certainly appears to influence how the linker handles them. --
Feb 12 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1830 Issue 1629 may be related. --
Feb 12 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1830 torhu yahoo.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID I believe this has to be fixed in the libraries that define constants as 'extern (Windows)'. Either don't use 'extern (Windows):', or use enums instead for manifest constants. If the whole file is 'extern (Windows):', another option might be to put the constants in 'extern (D)' blocks. 'extern (Windows)' gives the variables C name mangling. Which I believe is correct. Also see issue 1306. --
Feb 13 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1830 wbaxter gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|INVALID | A) Why should the name mangling affect whether the linker says it is a multiply-defined symbol? B) The error message says specifically "previous definition different" which is simply untrue. The previous definition was identical. extern(D), but then later say extern(Windows) is correct for these symbols. meaning that at the very least this is a bug against Phobos whose std.c.windows.windows module uses const rather than enum. --
Feb 13 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1830A) Why should the name mangling affect whether the linker says it is a multiply-defined symbol?The regular D name mangling convention adds the module name to the beginning of the mangled symbol, and the type at the end. If FOO in your module was extern (D), it would be mangled as '_D6link_a3FOOk'. For the other module, _D6link_b3FOOk. So there is no conflict when linking. With C name mangling on Windows, it's just _FOO in both cases. That's why the linker complains. To work around this, you can avoid linking with both modules. Since they only define an integer constant, you don't even need to link with any of them. Try it. :) Compiling one or both module into .lib files will work too, at least for your sample and other simple cases.B) The error message says specifically "previous definition different" which is simply untrue. The previous definition was identical.Might be a linker bug, I don't know. I doesn't matter if they identical or not, they can't have the same mangled name.extern(D), but then later say extern(Windows) is correct for these symbols.No, I just meant that C mangling is correct when using extern (Windows).meaning that at the very least this is a bug against Phobos whose std.c.windows.windows module uses const rather than enum.I'll agree with that. The title is probably wrong then. --
Feb 13 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1830 bugzilla digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution| |WONTFIX The problem is that the names for link_a.FOO and link_b.FOO are mangled the same when using extern(Windows), and are mangled differently when using extern(D), as the module name is part of the mangled name for D mangling. This is not fixable, as it is inherent with how Windows name mangling must work. The linker message means that there are two definitions of FOO. It doesn't matter to the linker that they have the same contents - the linker doesn't know that. The names collide. --
Mar 03 2008