execl 编译时的警告: warning: not enough variable arguments to fit a sentinel 解释说明(转载)

GCC 4 warnings about sentinels

Introduction

When compiling something with GCC 4, it may be possible that you get one of the following warnings:

warning: missing sentinel in function call
warning: not enough variable arguments to fit a sentinel

This document explains what these warnings mean and how to resolve them.

Sentinels & warnings

A sentinel is a special value which indicates the end of a series of data. In the context of GCC, it is a null pointer which ends a list of parameters to a function.

The function

execl(const char * path, const char * arg, ...)

 

takes a variable amount of parameters. To know where to stop reading parameters, the last parameter must be a null pointer. When you do not end the list with a null pointer, execl will not stop scanning, which will result in errors. The following code, therefore, is wrong:

 

#include <unistd.h>

int main() {
	execl("/bin/ls", "ls", "-l");
	return 0;
}

The execl function call is not terminated by a null pointer and GCC will give a warning. The following code is better:

#include <unistd.h>

int main() {
	execl("/bin/ls", "ls", "-l", NULL);
	return 0;
}

As you can see, the execl function is now terminated by a null pointer and it will stop scanning it's arguments after that. However, GCC 4 will still issue a warning:
warning: missing sentinel in function call
This is because NULL is not of the right type: it is defined as integer 0 instead of a pointer with the value 0. Doing an explicit cast can make the warning go away:

#include <unistd.h>

int main() {
	execl("/bin/ls", "ls", "-l", (char *)NULL);
	return 0;
}

Using sentinels

One can specify that a function uses a sentinel by declaring it as follows:

char * build_path(const char * str, ...) __attribute__((__sentinel__(0)));

This indicates that the parameter list is ended with the special value 0, which must be a char pointer.

On most systems, there is no difference between 0 and (char *)0. On 64 bit systems, however, the integer 0 is 32 bits and the pointer 0 is 64 bits. The compiler does not know whether it is an integer or a pointer, and defaults for the integer. This will not clear the upper 32 bits and the function will not stop scanning its parameters.

home | home

© Sjoerd Langkemper

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值