可变 C 函数中的空值
Nulls in variadic C functions
如果我定义了可变参数函数:
#include <stdio.h>
#include <stdarg.h>
int f(char*s,...)
{
va_list ap;
int i=0;
va_start(ap, s);
while(s)
{
printf("%s ", s);
i++;
s=va_arg(ap,char*);
}
va_end(ap);
return i;
}
int main()
{
return f("a","b",0);
}
gcc (linux x64) 编译它并且 exe 运行并打印 "a b ".
是否需要这样的演员表:
return f("a","b",(char*)0)
在普通系统上?
编译器不能为可变参数自动提升指针,例如,为什么当你想在 printf
中打印一个指针时,你必须将它转换为 void *
:
printf("%p", (void *)ptr);
相同的规则适用于所有可变参数函数,编译器无法知道您的函数需要一个 char *
,而 0 默认只是一个整数,所以是的,您需要转换它 (char *)0
.
甚至 NULL
也必须用你的函数 (char *)NULL
so why does main() work and when will it fail?
您的代码并非如此 "work"。您的代码调用未定义的行为,任何事情都可能发生,所以没有人能回答这个问题。在这里你很幸运,但下一次可能不会。
您的代码应该可以在任何支持 SYSV x64 ABI standard 的系统上正常工作。它可能在使用具有类似要求的其他一些 ABI 标准的系统上工作,并且可能在使用其他一些 ABI1 的任何系统上失败。根据 C 标准,这都是未定义的。
1特别是,Microsoft 不遵循标准 x64 ABI,他们有自己的标准。
如果我定义了可变参数函数:
#include <stdio.h>
#include <stdarg.h>
int f(char*s,...)
{
va_list ap;
int i=0;
va_start(ap, s);
while(s)
{
printf("%s ", s);
i++;
s=va_arg(ap,char*);
}
va_end(ap);
return i;
}
int main()
{
return f("a","b",0);
}
gcc (linux x64) 编译它并且 exe 运行并打印 "a b ".
是否需要这样的演员表:
return f("a","b",(char*)0)
在普通系统上?
编译器不能为可变参数自动提升指针,例如,为什么当你想在 printf
中打印一个指针时,你必须将它转换为 void *
:
printf("%p", (void *)ptr);
相同的规则适用于所有可变参数函数,编译器无法知道您的函数需要一个 char *
,而 0 默认只是一个整数,所以是的,您需要转换它 (char *)0
.
甚至 NULL
也必须用你的函数 (char *)NULL
so why does main() work and when will it fail?
您的代码并非如此 "work"。您的代码调用未定义的行为,任何事情都可能发生,所以没有人能回答这个问题。在这里你很幸运,但下一次可能不会。
您的代码应该可以在任何支持 SYSV x64 ABI standard 的系统上正常工作。它可能在使用具有类似要求的其他一些 ABI 标准的系统上工作,并且可能在使用其他一些 ABI1 的任何系统上失败。根据 C 标准,这都是未定义的。
1特别是,Microsoft 不遵循标准 x64 ABI,他们有自己的标准。