Базовая основа: почему анализатор LLVM сообщает, что вызывающая сторона не владеет объектом, созданным с помощью функции * Create *? - PullRequest
0 голосов
/ 07 июня 2018

Согласно Правиле создания Я создал свой собственный "конструктор" - CFStringCreateFromGoString.Он содержит «Создать» в своем названии.Я ожидаю, что если я вызову CFStringCreateFromGoString, то я имею возвращенный объект.

Но согласно статическому анализатору LLVM это не совсем так, и в некоторых случаях я получаю предупреждение Incorrect decrement of the reference count of an object that is not owned at this point by the caller - см. 1.h.А в других случаях, когда нет предупреждения - см. 2.h.

С common.h:

CFStringRef CFStringCreateFromGoString(_GoString_ str) {
    return CFStringCreateWithBytes(NULL, (UInt8*)_GoStringPtr(str), (CFIndex)_GoStringLen(str), kCFStringEncodingUTF8, false);
}

С 1.h:

CGRect _GetTextLineGeometry(CGContextRef context, _GoString_ str, CTFontRef font) {
    CFStringRef _str = CFStringCreateFromGoString(str);
    CGRect r = GetTextLineGeometry(context, _str, font); // no warning if I remove this line
    CFRelease(_str); // warning here
    return r;
}

С 2.h:

CTFontRef _CreateFontFromFile(_GoString_ path, struct FontSpec spec) {
    CFStringRef _path = CFStringCreateFromGoString(path);
    CTFontRef r = CreateFontFromFile(_path, spec);
    CFRelease(_path); // no warning
    return r;
}

Может кто-нибудь объяснить разницу между 1.h и 2.h?

Обновление 0

Спасибо за комментарий,Проблема была в GetTextLineGeometry - эта функция по ошибке выполнила CFRelease(_str).Теперь у меня нет предупреждений.Но я не понимаю, почему предупреждение было в _GetTextLineGeometry вместо GetTextLineGeometry?

1 Ответ

0 голосов
/ 07 июня 2018

Имя компонента «Создать» не выполняет никакой магии;это просто вопрос соглашения.Так что, в этом отношении, это понятие «владение».

Так что забудьте обо всем этом и просто подумайте о сохранении счета.

Статический анализатор, в отличие от простых людей, таких как вы ия, могу видеть весь твой код и могу считать.Он рассчитывает удержания и выпуски на этом объекте.Когда мы доберемся до CFRelease(_str) в вашем первом примере, вы ранее выпустили этот же объект, в результате чего его счетчик западений упал до нуля;так что в этот момент вы выполняете перевыпуск.Таким образом, статический анализатор помечает вас на этом этапе.

Теперь давайте вернемся и снова подумаем об этом с точки зрения «владения».Только «владелец» чего-либо может освободить это;это то, что означает «собственность».Но статический анализатор вполне может позволить вам передать право собственности, если вы знаете, что делаете.Так что, если вы хотите «взять на себя ответственность», выпустив GetTextLineGeometry, это нормально для статического анализатора.Но когда мы добираемся до CFRelease(_str), это второй"владелец" - и это не крикет.Таким образом, опять же, статический анализатор помечает вас здесь .

...