1

我正在尝试使用 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 无法表达的东西?

4

0 回答 0