1

在 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。

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

4

3 回答 3

1

好的,这就是我最终选择的。此答案基于我在 Rational DOORS DXL 论坛上找到的关于如何检查未分配变量的讨论。

我仍然不能完全理解它是如何工作的,但我的理解是它正在检查你传递给它的任何变量的内存地址,并且它的答案基于空对象似乎总是有一个地址的事实 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
于 2015-08-05T16:58:49.267 回答
0

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

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

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

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

解决方案: 我不太了解该addr_函数的作用,我假设它返回给定参数的地址。在上面的示例中,addr_返回值-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"
于 2018-08-22T07:08:14.597 回答
0

我看到你说的问题,看起来确实很奇怪。我的处理方式是:

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)

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

于 2015-08-05T14:40:45.550 回答