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

时间:2015-08-04 19:56:20

标签: ibm-doors

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

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

3 个答案:

答案 0 :(得分:1)

好的,这就是我最终选择的内容。这个答案基于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

答案 1 :(得分: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)

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

答案 2 :(得分: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"