在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。
为什么会发生这种情况,我该如何解决?
答案 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_
返回值-1
和0
,它们可能永远都不是有效地址,因此我对函数进行了如下修改并使其适用于我的用例:
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"