- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如题中所问:
What is the purpose of SAL (Source Annotation Language) and what is the difference between SAL 1 and SAL 2?
我了解用法的基础知识,这有助于突出传递给函数的每个变量的目的以及用于静态代码分析的各种其他内容,但它实际上有多大区别(忽略越来越清晰的对项目中其他程序员的参数要求)?
如果我有以下原型(prototype):
_Success_(return == 1)
int TestFunction( _In_ int* pTest, _Inopt_ char* pOptional );
这应该“告诉”静态分析器该函数在成功运行后将返回 1,pTest
是一个指针,不能为 nullptr
并且pOptional
是一个指针,它可以是也可以不是 nullptr
。但是,静态分析器不能从函数定义本身获取这些信息吗?此外,它如何处理获得的信息(例如成功标准)?
此外,为什么 SAL 1 和 SAL 2 之间存在差异,为什么微软决定改变他们命名宏的方式(即从 __out
到 _Out_
和__success
到 _Success_
?)
如果在 MSDN 的某个地方对此进行了详细描述,我很抱歉,但我无法在 StackOverflow 上找到它或任何其他问题的详细答案,所以我想我会问一下,希望能满足我的好奇心。
提前感谢您的宝贵时间!
最佳答案
我阅读了您问题中的多个问题,希望我能全部回答:
为什么要使用 SAL 而不仅仅是从源代码中推导?
关于使用 SAL 明确告诉分析器有关参数行为等详细信息的观点有多个答案。
虽然分析器可以从实现中推断出参数行为,但它通常无法区分实现的意图和意外。作为开发人员,如果您明确说明不同参数的预期用途,分析器既可以验证您编写的实现是否满足您的意图,也可以验证调用方是否正确使用了它。
当源代码不可用于分析时,这会为静态分析器提供有关函数行为的信息,例如在作为 Visual Studio、驱动程序套件等的一部分提供的各种头文件中声明的函数。
SAL 允许表达难以甚至不可能仅从源代码推断的概念,例如驱动程序中的锁使用和 IRQL 要求。
这也有助于与回调函数保持一致。 Windows header 描述的一些框架可能会声明一组回调函数,因此 Windows 框架将调用那些在别处(应用程序、驱动程序等)定义的回调函数。因此 Windows 永远看不到被调用函数的源代码,回调函数定义也永远看不到调用者。
分析器从成功中得到什么信息?
这与您编写的案例无关。但是在有输出参数的情况下(例如 Out 和 family),这意味着如果函数不成功,调用者不能依赖输出注释。例如:
_Success_(return) bool GetASmallInt(_Out_range_(0, 10) int& an_int);
如果 GetASmallInt 返回 true,则 an_int 将介于 0 和 10 之间,包括 0 和 10。如果它返回 false,则不存在这样的保证,并且该变量甚至可能还没有被函数初始化。
SAL 1 和 SAL 2 之间有什么区别,为什么注释从 __in
重命名为 _In_
?
SAL 的原始定义中的一些特殊情况(例如 __in)与 C++ 不能很好地融合。新语法从一些较新的实现开始,确保它符合 C 和 C++ 语法的要求。
SAL 1 和 SAL 2 之间的主要区别在于 SAL 2 能够表达很多 SAL 1 不能表达的概念,并且 SAL 2 定义得更好,尤其是在 C++ 方面,如上所述。
关于c++ - SAL(源注释语言)的目的是什么?SAL 1 和 2 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16265188/
我正致力于通过 OAuth 合并外部 API,但对 expires_in 属性的用途有点迷惑。通过阅读,应该对 api token 的使用进行防御性编码,因为您应该预料到 token 在任何时候都可能
有人可以概述或总结一下 Spring 框架上下文中 bean 的用途吗? 我了解标准的 Java bean(没有 arg 构造函数、getter/setter,通常是序列化的),但 Spring be
使用 OpenGL 4.1 和 ARB_separate_shader_objects,我们能够在着色器程序中存储着色管道的不同阶段。众所周知,要使用这些,我们需要将它们附加到程序管道对象,然后绑定(
正如我从文档中了解到的那样,“MoveIteratorFactory”的目的是生成每一步都需要执行的 Action 。 “getSize”方法的移动子集有多大? “createOriginalMove
请解释 CMakeLists.txt 中这一行的目的是什么: 包括(InstallRequiredSystemLibraries) 我在 CMake 示例中看到这一行,但找不到好的解释,为什么我需要它
这里是新手。我仍在尝试理解在多个布局中运行单个进程或目的的概念。 例如,我想在我的申请中添加“提交后”功能。有一个包含标题、内容等文本框的主布局,以及一个链接到另一个布局以选择类别的按钮。我的问题是,
我在看 Box Oauth2.0 View Controller : https://github.com/box/box-ios-sdk-v2/blob/master/BoxSDK/OAuth2/B
我编写了一个将字符串复制到系统剪贴板的 Java 应用程序。构造函数使用 Clipboard.setContents(Transferable contents, ClipboardOwner own
阅读此文后:http://sourcemaking.com/design_patterns/command 我还是不太明白为什么我们需要这个。 最佳答案 想法是,如果命令被封装为对象,那么这些命令可以
我知道 c++ 中的模板是做什么的,但是今天我看到了一些奇怪的代码: template <> void swap(foo &a, foo &b) { a.name = b.name; a.
我不太明白 C# Collections 中 IEnumerator 的用途是什么。它的用途是什么,为什么要使用它? 我试着在线查看 http://msdn.microsoft.com/en-us/l
不幸的是,我今天做了一些代码考古(同时重构了一些旧的危险代码)并发现了这样的小化石: # line 7 "foo.y" 能在里面找到如此古老的宝藏,我完全惊呆了。我在 C 编程的网站上阅读了它。然而,
您能否澄清一下此注释的实际用途? - 如果我们没有使用数据库中的 SQL 表定义定义相应的约束,会发生什么情况。当我们尝试插入时,hibernate 会检查唯一性吗?或者这就是DB的目的吗?如果 hi
我在视频教程中看到过这段代码: const navToggle = ["Menu"].join(""); $(".site-header").prepend(navToggle); 我明白它的基本作用
我想知道这个成员函数的 scroll_to(TextBuffer::iterator& iter, double within_margin = 0)参数 within_margin。 API 是这样
我想知道是否可以将子目录提交到目录例如,假设您有 site.com/directory 可以将子目录提交到目录。我即将开始为希望她的网站在搜索引擎中排名靠前的客户进行一些搜索引擎优化。我知道实现此目的
STL 迭代器的用途是什么?为什么程序员要创造这个概念? 最佳答案 迭代器允许您将算法与容器分开。只要您有开始和结束迭代器,并且知道迭代器的功能(随机访问等),您就可以在迭代器指定的范围内进行操作。例
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&respons
我正在编写代码,使用通用的 linux i2c 驱动程序 linux/i2c-dev.h 实现一个简单的 i2c 读/写功能 我对 ioctl 感到困惑:I2C_SLAVE 内核文档说明如下: You
在尝试克隆可变集合时,我最初的方法是对 mutable.Cloneable 特征使用 clone() 方法。但是,这取决于创建引用副本的 java.Object.clone 实现,而不是深拷贝。通过测
我是一名优秀的程序员,十分优秀!