我正在尝试使用 SAL 注释来防止在使用引用计数对象时出现某些可能的错误。此用例的特定注释不可用(据我所知),但使用锁定注释可以工作。
typedef struct RefCnt;
void
Reference(_Inout_ _Acquires_lock_(*_Curr_) RefCnt *R);
void
Unreference(_Inout_ _Releases_lock_(*_Curr_) RefCnt *R);
这将确保每次调用都会Reference
调用Unreference
,这正是我想要的。
然而,这留下了一些空白。如果我有一个引用计数的对象并且我有某种方法可以获取该对象,如果我没有取消引用它,我希望收到警告:
typedef struct
{
RefCnt R;
} Object;
Object global_obj;
Object *
GetObject(void)
{
Reference(&global_obj.R);
return &global_obj;
}
这将触发警告:warning C26165: Possibly failing to release lock 'global_obj.R' in function 'GetObject'.
,这是意料之中的。我可以对GetObject
函数进行注释,使其变为:_Acquires_lock_(_Curr_->R) Object *GetObject(void)
. 这解决了这个问题,但我可能会引入一个新问题,因为我没有收到任何这样的代码警告:
void
Test(void)
{
Object *o = GetObject();
// The reference counter is never reset, this is a leak, I should get a warning
}
如果我使用输出参数,它可以工作,void GetObject(_At_(*_Curr_, _Acquires_lock_(_Curr_->R)) Object **O)
解决方案也是如此,但我正在尝试改进直接返回对象的现有 API,所以我想避免进行这种更改。
有没有办法做到这一点,或者这是 SAL 无法表达的东西?