麻烦理解__attribute__标记

问题描述:

extern "C" int asnprintf (char **ret, size_t max_sz, const char *format, ...) 
    __attribute__ ((format (printf, 3, 4))); 

读取nmap的源代码我来了关于这个函数声明,我有麻烦理解它。麻烦理解__attribute__标记

以下是this webpage说一下:

基于

__attribute__((format(printf, m, n))); 

的(M)是 “格式字符串” 参数的数量,和(n)是多少第一个可变参数。

我不明白他说“格式字符串”时指的是什么;它们只是影响函数行为的参数吗?

此外,第一个可变参数的数量是多少?在所有的例子中,我看到它总是比m多一个,这是真的吗?你能举一个实际的例子吗?

谢谢。

extern "C" int asnprintf (char **ret, size_t max_sz, const char *format, ...) 
           ^1    ^2    ^3  ^4 

我不明白什么是他闯民宅说:“格式字符串”时;它们只是影响函数行为的参数吗?

格式字符串是你通常发现printf例如,像"%0.3f %s" ECC之一。当然这个功能也会相应地执行。

此外,第一个可变参数的数量是多少?在所有的例子中,我看到它总是比m多一个,这是真的吗?你能举一个实际的例子吗?

在这种情况下,m = 3n = 4,但不必如此。比方说,你有

int blablabla(const void *const data, const char *format, int data, ...) 

然后m = 2n = 4

+0

不可变参数 - 类型检查参数的开始。对于可变数量的参数,您不需要它。 .... f函数的编译器内建于gcc的类型检查 - 这就是此属性的原因 - 能够在程序员函数中使用此构建的功能。但是记住 - 它使你的代码不能移植。 –

+0

@PeterJ:我已经无处表示,它是在列表中一个可变参数的地方。然而,这是真的_unless_你在'format'中有'%d',所以'data'总是包含在内。 – edmz

+0

你的回答不正确。说实话 - 这远远不是正确的,或者可能是非常不准确的。 –

答案是在GCC手册:

格式属性指定一个函数具有printf,scanf的, 的strftime或风格的strfmon参数应该是类型检查 针对格式字符串。

格式(原型,字符串索引,第一 - 校验)

参数原型确定如何格式字符串 解释,并应printf和scanf函数,strftime或strfmon的。 (您 也可以使用的printfscanf函数的strftime的strfmon。)该 参数字符串索引指定哪个参数是格式字符串 参数(从1开始),而第一到检查是 第一个参数所要检查的格式串的数目。对于其中 参数不可用于进行检查的功能(如vprintf), 指定第三个参数为0。在这种情况下,编译器只有 检查格式字符串的一致性。对于strftime格式, 第三个参数需要为零。由于非静态C++方法 具有一个隐含的该参数,这样的方法的参数应该 从两个,而不是一个,当计数字符串的索引,并给予值 第一 - 校验。

+0

当输入不是可变参数时会发生什么?它会产生问题吗? – Garmekain

+0

我没试过。不知道 –