如何检查作为引用传递的变量中的空值

How to check for a null value in a variable passed as a reference

在 DXL 中,如何在将变量作为引用传递给函数后检查变量是否包含空值?使用 (null variableName) 的常用方法似乎无法正常工作:

void valueBasedNullTest(Buffer b) {
  print "Value based: "
  print "null b => "
  if (null b) {
    print "true"
  } else {
    print "false"
  }
  print "\n"
}

void referenceBasedNullTest(Buffer &b) {
  print "Reference based: "
  print "null b => "
  if (null b) {
    print "true"
  } else {
    print "false"
  }
  print "\n"
}

Buffer someBuffer = null
valueBasedNullTest(someBuffer)
referenceBasedNullTest(someBuffer)

结果:

Value based: null b => true
Reference based: null b => false

我目前 运行 Rational DOORS 9.2。

为什么会发生这种情况,我该如何解决?

我看到你说的这个问题,感觉确实很奇怪。我的处理方式是:

void referenceBasedNullTest(Buffer &b) {
  print "Reference based: "
  print "null b => "
  if (length(b) <=0) {
    print "true"
  } else {
    print "false"
  }
  print "\n"
}

Buffer someBuffer = create
//valueBasedNullTest(someBuffer)
referenceBasedNullTest(someBuffer)
delete(someBuffer)

这可以确保缓冲区存在,但您仍然可以测试它是否有任何内容。不要忘记在使用结束时删除Buffer。

好的,这就是我最终选择的。此答案基于 a discussion I found on the Rational DOORS DXL Forum 关于如何检查未分配的变量。

我仍然不能完全理解它是如何工作的,但我的理解是它正在检查你传递给它的任何变量的内存地址,并根据 null 对象似乎总是地址为 0。(欢迎证明我的错误。)

/*
Regular null check returns incorrect results in DOORS 9.2 under the following condition:

    void referenceBasedNullTest(Buffer &b) {
      print "Reference based: "
      print "null b => "
      if (null b) {
        print "true"
      } else {
        print "false"
      }
      print "\n"
    }

    Buffer someBuffer = null
    referenceBasedNullTest(someBuffer)

isNull works correctly in this case.
*/
bool isNull(_ &value) {
  int *intRef = (addr_ ((addr_ (value)) int))
  return (0 == *intRef)
}

无论如何,它似乎对我的目的很有效。

快速测试:

int nullInt = null
int blankInt = 0
int unassignedInt
int goodInt = 42

print "isNull(nullInt)\t\t=> "     isNull(nullInt) "\n"
print "isNull(blankInt)\t\t=> "    isNull(blankInt) "\n"
print "isNull(goodInt)\t\t=> "     isNull(goodInt) "\n"
print "isNull(unassignedInt)\t=> " isNull(unassignedInt) "\n"

print "\n"

Skip nullSkip = null
Skip blankSkip = create
Skip unassignedSkip

print "isNull(nullSkip)\t\t=> "     isNull(nullSkip) "\n"
print "isNull(blankSkip)\t\t=> "    isNull(blankSkip) "\n"
print "isNull(unassignedSkip)\t=> " isNull(unassignedSkip) "\n"

结果:

isNull(nullInt)        => true
isNull(blankInt)       => true  // Note: 0 is null for int values
isNull(goodInt)        => false
isNull(unassignedInt)  => false

isNull(nullSkip)       => true
isNull(blankSkip)      => false
isNull(unassignedSkip) => false

除了两种情况,@Ajedi32 的解决方案效果很好:

isNull(null) // --> causes an access violation

void foo(DxlObject &o) {
    isNull(o);
}
foo(null)    // --> causes an access violation

虽然有人会争辩说,第一种情况有点荒谬,但当我在其他一些函数中测试 null 时,后者经常发生。

解法: 我不太明白 addr_ 函数的作用,我假设它 returns 是给定参数的地址。 在上面的示例中,addr_ returns 值 -10,它们可能永远不是有效地址,因此我按如下方式修改了函数并使其正常工作对于我的用例:

bool isNull(_ &value) {
    if((addr_ value) == 0 || (addr_ value) == -1) {
        return true;
    }
    int *intRef = (addr_ ((addr_ (value)) int))
    return (0 == *intRef)
}

快速测试:

bool foo(DxlObject &o) {
    return isNull(o);
}

int nullInt = null
int blankInt = 0
int unassignedInt
int goodInt = 42

print "isNull(nullInt)\t\t=> "     isNull(nullInt) "\n"
print "isNull(blankInt)\t\t=> "    isNull(blankInt) "\n"
print "isNull(goodInt)\t\t=> "     isNull(goodInt) "\n"
print "isNull(unassignedInt)\t=> " isNull(unassignedInt) "\n"

print "\n"

Skip nullSkip = null
Skip blankSkip = create
Skip unassignedSkip

print "isNull(nullSkip)\t\t=> "     isNull(nullSkip) "\n"
print "isNull(blankSkip)\t\t=> "    isNull(blankSkip) "\n"
print "isNull(unassignedSkip)\t=> " isNull(unassignedSkip) "\n"
bool b = isNull(null);
print "isNull(null)\t\t=> "         b "\n"
b = foo(null);
print "foo(null)\t\t\t=> "          b "\n"