19

Some of these Preprocessor definitions are in the WinMain function and other windows library functions. What is their purpose? How do they work? and is it good practice to write them into your implementations or function calls?

My initial research suggests they're simply set up equlivalent to:

#define __in 
#define __out
#define __in_opt

Meaning they get replaced with nothing on the Preprocessor pass. Are they just a documentation method, without any functionality?

If so, I can see the advantage to documenting the code in line like this. With something like doxygen you need to write out the parameter names twice. So this could in theory help reduce duplication, and maintain consistency...

I have no theory for how __allowed() is supposed to work.

Lockyer
  • 1,311
  • 1
  • 13
  • 30

4 Answers4

24

They are SAL annotations in the Source-code Annotation Language. Microsoft tooling depends on it. The MSDN Library article is here. A good example is Code Analysis. Another quite unrelated tool, but empowered by these annotations is the Pinvoke Interop Assistant.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    Isn't it a problem when the tools depend on unreliable and incorrect information? – Cheers and hth. - Alf Nov 21 '10 at 20:16
  • It's always a problem when toolds depend on incorrect information. SAL annotations are no different. It's of course slightly risky, but that's inherent to C's declaration/definition architecture - you always have to make sure they match up. – MSalters Nov 22 '10 at 10:29
  • @Cheers SAL annotations are checked by Code Analysis both for the caller as well as the callee. The annotations not only express the author's intent but are also verified (where possible). As such they are neither unreliable nor incorrect. Consider `void foo( _In_opt_ int* p ) { *p = 42; }`. The parameter `p` is marked as optional but the implementation assumes that it will always be valid. Code Analysis will identify the issue and provide diagnostic information. – IInspectable Jul 13 '13 at 12:14
  • Correction to the code sample above, this should rather be: `void foo( _In_opt_ int* p ) { int i = *p; }` since it is an `_In_`-parameter. – IInspectable Jul 13 '13 at 12:29
  • @Tim: for example, as pointed out in my answer to this question, the annotations of the Windows API `MessageBox` function are simply wrong (or were wrong at the time of that answer, and had been wrong for a very long time). most annotations come from Microsoft, and they're unreliable. this comes on top of needless verbiage / visual clutter and no win for c++. – Cheers and hth. - Alf Jul 19 '13 at 01:05
9

SAL annotations are useful for two things:

  • Static analysis through PREfast (compile with /analyze)
  • Human readers can look at the annotations and figure out how a function should be called, and quickly determine the input/output parameters.

The macros do in fact expand to various declspec expressions when your code is compiled with analysis on. I use these annotations all the time in my code.

wj32
  • 8,053
  • 3
  • 28
  • 37
5

They're used in a Microsoft semantic analysis tool as code markups. Unless you plan on using this tool yourself, there's little purpose in using them.

Puppy
  • 144,682
  • 38
  • 256
  • 465
-3

These Microsoft macros generally expand to nothing, and are meant as hints to the reader.

However, last time I checked e.g. the hinting on the MessageBox arguments was completely wrong, hinting that first, second and third argument had useful defaults (when you specify 0), while in reality it's first and fourth argument that have useful defaults. Maybe also the title argument which defaults to "Error", but I've never found that useful. So, it's just a Microsoft thing, hints that you cannot and should not rely on, just misleading visual clutter.

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331