__in、__out、__in_opt和__allowed()的目的是什么?它们是如何工作的?我应该在我的代码中使用类似的结构吗?

19

这些预处理器定义中的一些位于WinMain函数和其他窗口库函数中。它们的目的是什么?它们如何工作?将它们编写到您的实现或函数调用中是否是最佳实践?

我的初步调研表明,它们简单地设置为相当于:

#define __in 
#define __out
#define __in_opt

这意味着它们在预处理(pass)阶段被替换为nothing。它们只是一种文档编写方法,没有任何功能吗?

如果是的话,我可以看到像这样内联编写代码的优点。使用像doxygen这样的工具,您需要两次编写参数名称。因此,理论上这可以帮助减少重复,并保持一致性......

我不知道__allowed()应该如何工作。

4个回答

24

它们是源代码注释语言中的SAL注解。微软工具依赖于它。MSDN Library文章在此。一个很好的例子是代码分析。另一个与此无关但受这些注释支持的工具是Pinvoke Interop助手。


1
当工具依赖于不可靠和错误的信息时,这难道不是一个问题吗? - Cheers and hth. - Alf
当工具依赖于不正确的信息时,这总是一个问题。 SAL注释也不例外。 这当然稍微有点冒险,但这是C语言声明/定义体系结构所固有的 - 你总是要确保它们匹配。 - MSalters
@Cheers SAL注释会被代码分析工具检查,无论是调用者还是被调用者。这些注释不仅表达了作者的意图,而且在可能的情况下也得到了验证。因此,它们既不会不可靠,也不会不正确。考虑void foo( _In_opt_ int* p ) { *p = 42; }。参数p被标记为可选,但实现假定它始终有效。代码分析将识别该问题并提供诊断信息。 - IInspectable
以上代码示例有所更正,应该改为:void foo( _In_opt_ int* p ) { int i = *p; },因为它是一个 _In_ 参数。 - IInspectable
@Tim:例如,正如我在回答这个问题时指出的那样,Windows API的MessageBox函数的注释是完全错误的(或者在那篇回答时是错误的,而且已经错误了很长时间)。大多数注释都来自于微软,它们是不可靠的。这还需要增加不必要的废话/视觉杂乱和对C++没有贡献。 - Cheers and hth. - Alf

9

SAL注释在两个方面非常有用:

  • 通过PREfast进行静态分析(使用/analyze编译)
  • 人类读者可以查看注释并确定如何调用函数,快速确定输入/输出参数。

当您的代码启用分析时,宏确实会扩展为各种declspec表达式。我经常在我的代码中使用这些注释。


5

它们被用作微软语义分析工具中的代码标记。除非您打算自己使用此工具,否则使用它们的意义不大。


-3

这些微软宏一般情况下不会展开任何内容,而是作为给读者的提示。

然而,上次我检查时例如 MessageBox 参数的提示完全是错误的,提示第一个、第二个和第三个参数具有有用的默认值(当你指定0时),但实际上只有第一个和第四个参数有用的默认值。也许标题参数也有一个默认值,即“Error”,但我从未发现过其有用。所以,这只是微软的东西,是不能且不应该依赖的提示,只是误导性的视觉杂乱。

祝好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接