繁体   English   中英

用NULL强制结束可变参数函数参数

[英]Enforcing ending variadic function parameters with NULL

是否可以进行可变参数的声明,使其不以“ ...”结尾?

今天,我从unistd.h了解了更多关于exec的信息,但是直到今天,我已经看到了三(实际上是两个)不同的execl声明:

1) int execl ( const char * path, const char * arg0, ..., (char*)NULL ); 是在学校给我们看的,我想我必须以NULL值结束函数调用

2) int execl(const char *path, const char *arg, ... /* (char *) NULL */); 是我在exec(3)手册页中找到的内容。 那可能意味着我仍然必须以NULL值结尾,但是没有强制执行。

3) int execl(const char *path, const char *arg, ...); 这就是我在这里找到的。 通常,这可能会让我休息,第一个是对学生的简化,第二个是变种,这是真实的(尽管我通常对选项一和选项二都比较重视。)

但是后来我在同一站点上发现了这个声明:

int execle(const char *path, const char *arg, ..., char * const envp[]);

出现同样的问题,我无法创建不以...结尾的可变参数函数,gcc告诉我它')' before ',' token')' before ',' token在三个点后指向逗号。

因此,最后,是否可以使可变参数函数以NULL字符结尾(execl),否则,是否可以使它以预定义变量结尾(execle)?

我尝试使用gcc 6.3.1进行编译,也尝试了--std = c11。

是否可以进行可变参数的声明,使其不以“ ...”结尾?

可能是一个棘手的问题,但请考虑以下事实:

  • 该标准说:“如果定义了接受可变数量参数的函数而没有以省略号结尾的参数类型列表,则行为是不确定的”(C2011,6.9.1 / 8)

也许已经回答了这个问题,但是如果您选择将单词切成小段并专注于定义的函数声明,那么

  • 函数定义也是声明
  • C语言标准要求同一功能的所有声明都是“兼容的”(其他程序行为未定义)(C2011 6.7 / 4)
  • 参数列表不匹配的两个函数声明不兼容(C2011,6.2.7 / 3)

因此,如果您声明实际上也已定义的可变参数函数,并且该函数的参数列表不以... 结尾 ,则该程序的行为是不确定的。


您一直在阅读execle()execl()的文档是为了表达和讨论这些函数的期望而编写的,但是在某种程度上似乎呈现了可变参数声明,而参数列表的最后一个元素不是... ,这些实际上不是有效的C函数声明。

因此,最后,是否可以使可变参数函数以NULL字符结尾(execl),否则,是否可以使它以预定义变量结尾(execle)?

无法通过符合标准的C声明来描述此类调用约定。 可变参数函数可以有这样的期望,并且可以在运行时强制执行,但是只有在依赖于所涉及函数的特殊知识的编译器或允许描述此类约束的C语言扩展的情况下,才能在编译时强制执行它们。

可变参数函数的声明只能指定所需的参数,并且编译器可以强制执行其类型。 可变长度部分永远不会进行任何类型检查。 可变长度部分始终在末尾。 execle()的声明并不意味着实际的C声明,而只是向程序员描述他应该如何构造参数。

不能强制execl()的最后一个参数为NULL 可变参数函数不知道提供了多少个参数,而是根据参数的值确定参数。 printf()假定它有足够的参数来填充格式字符串中的所有运算符,并且execl()遍历这些参数,直到找到NULLexecle()是相似的,但它读取一个附加参数来获取envp )。 如果不以NULL结尾,它将继续下去,读取垃圾并引起未定义的行为。

您看到的声明是execl手册页中的声明。 glib中execle的声明如下: int execle (const char *path, const char *arg, ...) 该实现假定最后一个参数是char **,并将其用于envp。 我认为您无法在C中执行这样的规则。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM