Аннотации для разыменования NULL в Prefast и компиляции на GCC - PullRequest
0 голосов
/ 20 сентября 2011

У меня есть следующий пример кода и я хотел бы знать, какие аннотации я могу использовать, чтобы их избежать.

int Function(classA* pInput) {
   if (pInput == NULL) {
      classA::Create(pInput);
   }

   return pInput->value;
}

Проблема в том, что, поскольку Prefast оценивает только функцию, он не знает, что Create инициализирует указатель.

Я думал, что смогу решить эту проблему, используя аннотацию __out в заголовочном файле для classA::Create, однако это не сработало.

Мне интересно, есть ли хорошая альтернатива просто __analysis_assume повсюду в коде, чтобы префаст выбирал ее из определения функции.

Во-вторых, Мне было интересно, как я могу настроить свою конфигурацию сборки так, чтобы я мог создавать свой код непосредственно на Linux или с GCC с этими директивами препроцессора. Должен ли я проверить, находится ли он в сборке LINUX, а затем добавить эти аннотации в виде пустых макросов?

Ответы [ 2 ]

2 голосов
/ 21 сентября 2011

MSalter's answer очень похоже на правильный технический ответ.К счастью, я не знаю SAL, поэтому не могу сказать наверняка, но похоже, что это решение технического уровня.

Однако я бы порекомендовал вам переписать ваш текущий код…

int Function(classA* pInput) {
   if (pInput == NULL) {
      classA::Create(pInput);
   }

   return pInput->value;
}

as…

int Function( classA* pInput ) {
   if (pInput == NULL) {
      pInput = classA::Create();
   }

   return pInput->value;
}

Основная проблема здесь в том, является ли утечка динамически созданным объектом или нет.Это очень сильно зависит от того, что делает метод Create.Но похоже, что у вас утечка.

И в этом случае, когда Create не делает ничего, кроме динамического выделения инициализированного по умолчанию объекта classA, то вот как вы можете сделать это более безопасно и более эффективно:

int Function( classA* pInput ) {
   if (pInput == NULL) {
      return classA().value;
   }

   return pInput->value;
}

Наконец, для полной очистки подумайте, как избавиться от ненужных необработанных указателей.Потому что сырые указатели создают проблемы (ваш код является лишь небольшим примером этого).Затем вы можете сделать что-то вроде этого:

int function( ClassA const& anObject = ClassA() )
{
   return anObject.value;
}

По сути, это решение уровня C ++, в отличие от уровня C исходного кода.Таким образом, я изменил также соглашение об именах, чтобы отразить более сильный акцент на типах на уровне C ++.Здесь типы имеют заглавную первую букву, а простая функция имеет строчную первую букву.

Это проще, безопаснее, опять же эффективнее.

И - на уровне C ++ вы обычно не делаетенужно бороться с глупыми нотациями SAL.: -)

Приветствия и hth.,

1 голос
/ 20 сентября 2011

Похоже, что SA отсутствует [Post( Null=No )] в параметре classA*& classA::Create(classA*)

...