www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Linker Errors when Constructing an Immutable Struct

reply "Adam Wilson" <flyboynw gmail.com> writes:
Please consider the following code:

module aurora.immediate.input;

public enum Key : int { //... }

public immutable struct KeyData
{
	private Key _key;
	 property public Key KeyCode() { return _key; }

	private bool _isDown;
	 property public bool IsDown() { return _isDown; }

	private bool _isUp;
	 property public bool IsUp() { return _isUp; }

	private bool _isRepeating;
	 property public bool IsRepeating() { return _isRepeating; }

	 disable this();

	public immutable this(Key key, bool isDown, bool isUp, bool isRepeating =  
false) nothrow
	{
		_key = key;
		_isDown = isDown;
		_isUp = isUp;
		_isRepeating = isRepeating;
	}
}

module aurora.immediate.window;
import aurora.immediate.input;

public class Window {
protected void delegate(immutable(KeyData) args) nothrow onKeyDown;
private LRESULT internalWndProc(HWND hwnd, UINT message, WPARAM wParam,  
LPARAM lParam) nothrow {
	if (onKeyDown !is null) onKeyDown(immutable KeyData(cast(Key)wParam,  
true, false, false));
	return 0;
}
}

When compiled and imported as a static library it fails to compile with  
the following linker errors:
libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019: unresolved  
external symbol _D6aurora9immediate5input7KeyData6__initZ referenced in  
function _D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl
libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019: unresolved  
external symbol  
_D6aurora9immediate5input7KeyData6__ctorMyFNbNcE6aurora9immediate5input3KeybbbZyS6aurora9imm
diate5input7KeyData  
referenced in function  
_D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl

It appears that the linker cannot find .init and the .ctor. Is this a  
compiler bug or am I doing something wrong? I am wondering if this is a  
problem with immutable structs? Any pointers would be very appreciated.

-- 
Adam Wilson
GitHub/IRC: LightBender
Aurora Project Coordinator
Jun 02 2014
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Mon, 02 Jun 2014 00:13:32 -0700
Adam Wilson via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Please consider the following code:

 module aurora.immediate.input;

 public enum Key : int { //... }

 public immutable struct KeyData
 {
   private Key _key;
    property public Key KeyCode() { return _key; }

   private bool _isDown;
    property public bool IsDown() { return _isDown; }

   private bool _isUp;
    property public bool IsUp() { return _isUp; }

   private bool _isRepeating;
    property public bool IsRepeating() { return _isRepeating; }

    disable this();

   public immutable this(Key key, bool isDown, bool isUp, bool
 isRepeating = false) nothrow
   {
       _key = key;
       _isDown = isDown;
       _isUp = isUp;
       _isRepeating = isRepeating;
   }
 }

 module aurora.immediate.window;
 import aurora.immediate.input;

 public class Window {
 protected void delegate(immutable(KeyData) args) nothrow onKeyDown;
 private LRESULT internalWndProc(HWND hwnd, UINT message, WPARAM
 wParam, LPARAM lParam) nothrow {
   if (onKeyDown !is null) onKeyDown(immutable
 KeyData(cast(Key)wParam, true, false, false));
   return 0;
 }
 }

 When compiled and imported as a static library it fails to compile
 with the following linker errors:
 libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019:
 unresolved external symbol _D6aurora9immediate5input7KeyData6__initZ
 referenced in function
 _D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl
 libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019:
 unresolved external symbol
 _D6aurora9immediate5input7KeyData6__ctorMyFNbNcE6aurora9immediate5input3KeybbbZyS6aurora9immediate5input7KeyData
 referenced in function
 _D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl

 It appears that the linker cannot find .init and the .ctor. Is this
 a compiler bug or am I doing something wrong? I am wondering if this
 is a problem with immutable structs? Any pointers would be very
 appreciated.
It's probably a bug, though I'd point out that all it means when you mark a struct declaration as immutable is that you've marked all of its members as immutable (meaning that marking the constructor as immutable is redundant). Also, if all of the member variables are immutable, there really isn't much point in declaring getters. You might as well just make them public. Regardless, I don't know why you'd be getting the errors that you're getting. You could try just marking all of the members as immutable directly and removing the getters and seeing if that magically fixes things for you (though it probably won't). It does sound like a compiler bug though. - Jonathan M Davis
Jun 02 2014
parent "Adam Wilson" <flyboynw gmail.com> writes:
On Mon, 02 Jun 2014 00:42:07 -0700, Jonathan M Davis via Digitalmars-d  
<digitalmars-d puremagic.com> wrote:

 On Mon, 02 Jun 2014 00:13:32 -0700
 Adam Wilson via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Please consider the following code:

 module aurora.immediate.input;

 public enum Key : int { //... }

 public immutable struct KeyData
 {
   private Key _key;
    property public Key KeyCode() { return _key; }

   private bool _isDown;
    property public bool IsDown() { return _isDown; }

   private bool _isUp;
    property public bool IsUp() { return _isUp; }

   private bool _isRepeating;
    property public bool IsRepeating() { return _isRepeating; }

    disable this();

   public immutable this(Key key, bool isDown, bool isUp, bool
 isRepeating = false) nothrow
   {
       _key = key;
       _isDown = isDown;
       _isUp = isUp;
       _isRepeating = isRepeating;
   }
 }

 module aurora.immediate.window;
 import aurora.immediate.input;

 public class Window {
 protected void delegate(immutable(KeyData) args) nothrow onKeyDown;
 private LRESULT internalWndProc(HWND hwnd, UINT message, WPARAM
 wParam, LPARAM lParam) nothrow {
   if (onKeyDown !is null) onKeyDown(immutable
 KeyData(cast(Key)wParam, true, false, false));
   return 0;
 }
 }

 When compiled and imported as a static library it fails to compile
 with the following linker errors:
 libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019:
 unresolved external symbol _D6aurora9immediate5input7KeyData6__initZ
 referenced in function
 _D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl
 libaurora_immediate64d.lib(window_47a_278.obj) : error LNK2019:
 unresolved external symbol
 _D6aurora9immediate5input7KeyData6__ctorMyFNbNcE6aurora9immediate5input3KeybbbZyS6aurora9immediate5input7KeyData
 referenced in function
 _D6aurora9immediate6window6Window15internalWndProcMFNbPvkmlZl

 It appears that the linker cannot find .init and the .ctor. Is this
 a compiler bug or am I doing something wrong? I am wondering if this
 is a problem with immutable structs? Any pointers would be very
 appreciated.
It's probably a bug, though I'd point out that all it means when you mark a struct declaration as immutable is that you've marked all of its members as immutable (meaning that marking the constructor as immutable is redundant). Also, if all of the member variables are immutable, there really isn't much point in declaring getters. You might as well just make them public. Regardless, I don't know why you'd be getting the errors that you're getting. You could try just marking all of the members as immutable directly and removing the getters and seeing if that magically fixes things for you (though it probably won't). It does sound like a compiler bug though. - Jonathan M Davis
Ok, i'll report it then. I've tried the constructor both with and without the redundant immutable tag, because sometimes DMD has takes-one-but-not-the-other bugs. I actually tried it a bunch of different ways, with getters, without getters, with individual immutable, without, etc. No dice. -- Adam Wilson GitHub/IRC: LightBender Aurora Project Coordinator
Jun 02 2014