www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - LNK2019 error from using a function pointer to core.bitop functions?

reply "Matthew Gamble" <gamblemj gmail.com> writes:
This member function of my struct uses a function pointer btx. 
When the line declaring the function pointer is present I get a 
LNK2019 error: unresolved external symbol.

bool opIndexAssign(bool value, size_t[2] inds)
{
	int function(size_t*, size_t) btx = (value) ? &bts : &btr; // 
error is here
		
         // other stuff here
		
	for (size_t i = startBitInd; i < startWordBitDone; ++i) 
btx(&bitArray[startWord], i);
		
         // other stuff here

	if (startWord != stopWord) for (size_t i = 0; i < stopBitInd; 
++i) btx(&bitArray[stopWord], i);
	return value;
}


However, when I don't use the function pointer and instead call 
bts directly (as outlined below, the program compiles and links 
just fine.

bool opIndexAssign(bool value, size_t[2] inds)
{
			
         // other stuff here
		
	for (size_t i = startBitInd; i < startWordBitDone; ++i) 
bts(&bitArray[startWord], i);
		
         // other stuff here

	if (startWord != stopWord) for (size_t i = 0; i < stopBitInd; 
++i) bts(&bitArray[stopWord], i);
	return value;
}

Any ideas how to fix this behavior? I was trying to use the 
function pointer so I wouldn't need to write essentially the same 
code block replacing bts with btr in if and else blocks

Any help would be appreciated. Thanks
Jul 15 2015
parent reply "Roland Hadinger" <rolandh.dlangforum maildrop.cc> writes:
On Thursday, 16 July 2015 at 03:24:54 UTC, Matthew Gamble wrote:
 This member function of my struct uses a function pointer btx. 
 When the line declaring the function pointer is present I get a 
 LNK2019 error: unresolved external symbol.
Just guessing, probably because bts and btr are intrinsics? If performance is not that important, you can always do this at the start of your opIndexAssign method: static int bts(size_t* p, size_t bitnum) { return .bts(p, bitnum); } static int btr(size_t* p, size_t bitnum) { return .btr(p, bitnum); } int function(size_t*, size_t) btx = (value) ? &bts : &btr; Otherwise, I'd use templates and an alias. Maybe this will result in faster code: bool opIndexAssign(bool value, size_t[2] inds) { void impl(bool b)(size_t[2] inds) { static if(b) alias btx = bts; else alias btx = btr; // code from opIndexAssign goes here... // for (size_t i = startBitInd; ... } if( value ) impl!true(inds); else impl!false(inds); }
Jul 17 2015
parent reply "Roland Hadinger" <rolandh.dlangforum maildrop.cc> writes:
On Friday, 17 July 2015 at 15:47:39 UTC, Roland Hadinger wrote:
 Otherwise, I'd use templates and an alias. Maybe this will 
 result in faster code:

     bool opIndexAssign(bool value, size_t[2] inds)
     {
         void impl(bool b)(size_t[2] inds)
         {
             static if(b)
                 alias btx = bts;
             else
                 alias btx = btr;

             // code from opIndexAssign goes here...
             // for (size_t i = startBitInd; ...
         }

         if( value )
             impl!true(inds);
         else
             impl!false(inds);
return value; // oops
     }
Jul 17 2015
parent "Matthew Gamble" <gamblemj gmail.com> writes:
On Friday, 17 July 2015 at 15:49:46 UTC, Roland Hadinger wrote:
 On Friday, 17 July 2015 at 15:47:39 UTC, Roland Hadinger wrote:
 Otherwise, I'd use templates and an alias. Maybe this will 
 result in faster code:

     bool opIndexAssign(bool value, size_t[2] inds)
     {
         void impl(bool b)(size_t[2] inds)
         {
             static if(b)
                 alias btx = bts;
             else
                 alias btx = btr;

             // code from opIndexAssign goes here...
             // for (size_t i = startBitInd; ...
         }

         if( value )
             impl!true(inds);
         else
             impl!false(inds);
return value; // oops
     }
Roland, both of your solutions work perfectly. Thank you. You brought up the issue of performance. Performance may be an issue for certain use-cases when the function is called many times and the values of inds[1] - inds[0] is small (e.g less than 257). In these cases at least half the work in the function will be done with bts/btr. However, for larger ranges there is an optimization (not shown) that eliminates the need to call bts/btr in the middle region of the range. Why do you think the second solution would be faster than the first? And do you also think that the rolled out version replicating the code in the "if" and "else" blocks replacing bts with btr would be even faster since it eliminates the need for any additional function call? I guess I'll have to profile all three versions when my program matures enough be used with a "big" data example. Sorry for all the questions. I really appreciate your help. Best, Matt
Jul 17 2015