2

Is it possible to make declaration of variadic function so that it doesn't end with "..."?

Today I learned more about exec from unistd.h but through the day I've seen three (two actually) different declaration of execl:

1) int execl ( const char * path, const char * arg0, ..., (char*)NULL ); was shown to us in school and I imagined I would have to end the function call with a NULL value

2) int execl(const char *path, const char *arg, ... /* (char *) NULL */); is what I've found in the exec(3) man page. That would probably mean I still have to end it with a NULL value, but it is not enforced.

3) int execl(const char *path, const char *arg, ...); is what I found here. This one would probably normally put me to rest with the first one being a simplification for students, the second was a varning and this is the real thing (even though I would probably have normally higher regard for both options one and two.)

But then I found on the same site this declaration:

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

Same question applies, I was unable to create variadic function not ending in ... with gcc telling me that it's expecting ')' before ',' token pointing to the comma after the three dots.

So finally, is it possible to make variadic functions ending with a NULL characters (execl) and if not, is it possible to make it end with predefined variable (execle)?

I tried to compile with gcc 6.3.1, I also tried --std=c11.

4

3 回答 3

4

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

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

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

也许这已经回答了这个问题,但是如果您选择扼杀文字并专注于不是定义的函数声明,那么

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

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


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

最后,是否可以使可变参数函数以 NULL 字符(execl)结尾,如果没有,是否可以使其以预定义变量(execle)结尾?

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

于 2017-03-23T19:01:06.000 回答
1

可变参数函数的声明只能指定所需的参数,编译器可以强制它们的类型。可变长度部分从未完成任何类型检查。可变长度部分总是在最后。for 的声明execle()并不意味着作为一个实际的 C 声明,而只是向程序员描述他应该如何构造参数。

不可能强制执行最后一个参数execl()NULL。可变参数函数不知道提供了多少参数,它们根据参数的值来确定。printf()假设它有足够的参数来填充格式字符串中的所有运算符,并execl()遍历参数直到找到NULL(execle()类似,但它读取一个额外的参数来获取envp)。如果您不以 结尾NULL,它将继续运行,读取垃圾并导致未定义的行为。

于 2017-03-23T18:48:37.000 回答
1

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

于 2017-03-23T19:01:50.273 回答