开发者

Annotations for NULL Dereference in Prefast and Compiling on GCC

开发者 https://www.devze.com 2023-04-06 09:47 出处:网络
I have the following example code and would like to know what kind of annotations I can use to avoid them.

I have the following example code and would like to know what kind of annotations I can use to avoid them.

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

   return pInput->value;
}

The problem is that since Prefast evaluates only the function it doesn't know that Create initializes the pointer.

I thought I could solve开发者_Python百科 it by using the __out annotation in the header file for classA::Create however that didn't work.

I'm wondering if there is a good alternative to just __analysis_assume everywhere in the code such that prefast picks it up from the function definition.

Secondly, I was wondering how would I set up my build configuration so that I can build my code natively on Linux or with GCC with these preprocessor directives. Would I have to check if it's on a LINUX build and then add those annotations as empty Macros?


MSalter’s answer sounds very much like the correct technical answer. Happily I don't know SAL so I can't say for sure, but it looks like the technical level solution.

However, I would just recommend that you rewrite your current code …

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;
}

The main issue here is whether you're leaking a dynamically created object, or not. That depends very much on what the Create method does. But it does look like you're leaking.

And in that case, where Create does nothing but dynamically allocate a default-initialized classA object, then here is how you can do that more safely and more efficiently:

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

   return pInput->value;
}

Finally, for a total clean-up consider how to get rid of unnecessary raw pointers. Because raw pointers create problems (your code being just a very small example of that). Then you can do things like this:

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

Essentially this is a C++ level solution, as opposed to the original code's C level. So I changed also the naming convention to reflect the much stronger focus on types at the C++ level. Here the types have uppercase first letter, and a mere function has lowercase first letter.

It's simpler, it's safer, it's again more efficient.

And – at the C++ level you generally don't have to struggle with silly SAL notations. :-)

Cheers & hth.,


Seems like SA is missing [Post( Null=No )] on the classA*& parameter of classA::Create(classA*)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号