__attribute__((sentinel))

原创 2015年11月19日 17:43:03

__attribute__((sentinel))的作用是提醒程序员:“此可变参数函数需要一个NULL作为最后一个参数。”,而这个NULL参数一般被叫做“哨兵参数”。

比如下面这段程序:

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <malloc.h>

void foo(char *first, ...)
{
    char *p = (char *)malloc(100), *q = first;
    va_list args;

    va_start(args, first);
    while(q)
    {
        strcat(p, q);
        q = va_arg(args, char *);
    }
    va_end(args);
    printf("%s\n", p);

    free(p);

    return ;
}

int main(void)
{
    foo("Hello", "World");

    return 0;
}

使用

gcc main.c -Wall

编译没有任何警告。但是很显然,调用foo()时最后一个参数应该是个NULL以表明“可变参数就这么多”。
程序的运行结果:

HelloWorldm1�i�

显然是错误的。
另:这段程序在某些时候可能运行正常,那是因为在当时的情况下内存中存放”World”字符串的后面正好是个0(也就是NULL)。
将调用foo()的地方改为

foo("Hello", "World", NULL);

才是正确的写法。

但是为什么这种问题编译器不发出警告?那是因为你没有让编译器发出这类问题的警告,因为不是所有可变参数函数都需要哨兵参数,比如printf()。

/* 第一个参数中规定了有两个待打印项,所以打印时会取"string"1,
 * 多写的"another_string"会被忽略。
 * printf()在被调用时明确知道此次调用需要多少个参数,所以也就无需哨兵参数的帮忙。
 */
printf("%s %d\n", "string", 1"another_string");

所以__attribute__((sentinel))的功能就在于此。我们把上面的程序改一下,加一句foo()的声明:

void foo(char *first, ...) __attribute__((sentinel));

这样你再不写哨兵参数,在编译时编译器就会发出警告了:

main.c: In function ‘main’:
main.c:28:5: warning: missing sentinel in function call [-Wformat=]
foo(“Hello”, “World”);
^

版权声明:本文为博主原创文章,未经博主允许不得转载。

c语言中的_attribute_的意义

我们在进行定义数据结构计算数据结构大小的时候,或者进行网络通讯的socket发送数据的时候,都会遇到一个共同的问题:数据对齐问题。 这个问题是硬件为提高访问数据的效率,引出的问题,这里就不具体说...
  • wsclinux
  • wsclinux
  • 2017年03月28日 23:20
  • 457

__attribute__使用的一些总结

(ZT)GNU C 的 __attribute__ 机制 2011-11-10 19:02 ----------------------------------------------...
  • zb872676223
  • zb872676223
  • 2014年10月09日 13:31
  • 1258

STM32学习笔记之__attribute__ ((at())绝对定位分析

学习STM32也会遇到这样的绝对定位的问题如下: uint8_t   UART_RX_BUF[1024]   __attribute__ ((at(0X20001000)));   //就是将串口接收...
  • sinat_23338865
  • sinat_23338865
  • 2016年07月19日 23:26
  • 5774

RealView编译器常用特有功能

一. 关键字和运算符 1. __align(n):指示编译器在n 字节边界上对齐变量。        对于局部变量,n 值可为 1、2、4 或 8。        对于全局变量,n 可以具有最...
  • zhzht19861011
  • zhzht19861011
  • 2013年03月07日 10:54
  • 5744

__attribute__使用的一些总结

以前用VC时没感觉VC有什么问题,现在终于用到了VC不支持的功能 :-) 现在做个小小的总结 更多见 http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Fu...
  • lubing20044793
  • lubing20044793
  • 2014年06月11日 21:49
  • 1097

__attribute__ 你知多少?

__attribute__ 你知多少? GNU C 的一大特色就是__attribute__ 机制。__attribute__ 可以设置函数属性(Function Attribute )、变量属性(...
  • dayancn
  • dayancn
  • 2016年04月08日 21:15
  • 1185

关于__attribute__中section部分的一些了解

诸如我辈菜鸟,对编译器了解比较少,面对代码中出现的陌生字眼真是茫然不知所措。今天查阅了一些资料,总算是有了一点了解,现在将些许理解记录在案。 __attribute__这个关键词是GNU编译器中的...
  • zddxmu
  • zddxmu
  • 2013年07月23日 11:40
  • 12547

__attribute__ 你知多少?

转载自:http://www.cnblogs.com/astwish/p/3460618.html GNU C 的一大特色就是__attribute__ 机制。__attribute...
  • sangyongjia
  • sangyongjia
  • 2015年11月20日 16:45
  • 1020

__attribute__函数的作用

[iOS]__attribute__ 标签: iOS 2016-09-07 19:41 107人阅读 评论(0) 收藏 举报  分类: iOS开发(52)  ...
  • yu132563
  • yu132563
  • 2016年12月01日 21:07
  • 525

[随笔]gcc的__attribute__编译属性

注:此文非原创,是博主在学习过程中网络摘抄整理而出。gcc的__attribute__的编绎属性__attribute__主要用于 改变所声明或定义的函数或数据的特性,它有很多子项,用于改变作用对象的...
  • itxiebo
  • itxiebo
  • 2016年03月16日 14:56
  • 1703
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:__attribute__((sentinel))
举报原因:
原因补充:

(最多只允许输入30个字)