January 25, 2014
I'm beginning to implement structs in my ARM Cortex-M runtime, and I ran across something interesting today.

Consider this struct:
struct TestStruct
{
    uint TestVar;

    void Print()
    {
	trace.WriteLine("TestStruct.Print");
    }
}

And a function that uses that struct:
void MyFunction()
{
    TestStruct test;
    test.Print()
}

Adding this function call created a unresolved reference to _d_assert_msg. When I look at the code generations I see this:
 start.TestStruct.Print (struct start.TestStruct & this)
{
  struct  D.3650;
  const struct  t;
  struct  D.3627;
  struct  D.3626;

  <bb 2>:
  if (this_1(D) != 0)
    goto <bb 4>;
  else
    goto <bb 3>;

  <bb 3>:
  D.3626.length = 9;
  D.3626.ptr = "null this";
  D.3627.length = 14;
  D.3627.ptr = "source/start.d";
  _d_assert_msg (D.3626, D.3627, 26);

  <bb 4>:
  MEM[(struct  *)&t] = 16;
  MEM[(struct  *)&t + 4B] = "TestStruct.Print";
  Write (t);
  t ={v} {CLOBBER};
  D.3650.length = 2;
  D.3650.ptr = "\r\n";
  Write (D.3650);
  return;

}

What bothers me is the branch at <bb 2>. It looks like it's checking the struct instance to see if it is null. Is it even possible for it to be null?  Can this be improved?

I imagine in a tight loop (for example, an alpha blend function on an array of pixels), this can be a significant performance hindrance if every call has to make this check.

I'd be happy to submit a bug report if you think this has merit.

Mike
January 25, 2014
"Mike"  wrote in message news:lxusmgyievzioacmgwmc@forum.dlang.org...
> What bothers me is the branch at <bb 2>. It looks like it's checking the struct instance to see if it is null. Is it even possible for it to be null?  Can this be improved?

It's checking if the 'this' pointer is null.  Syntactically it's a 'this' _reference_, but it can still be null.

void MyFunction()
{
    TestStruct *test;
    test.Print()
}

> I imagine in a tight loop (for example, an alpha blend function on an array of pixels), this can be a significant performance hindrance if every call has to make this check.

It should disappear when compiled with '-frelease'.