完全忽略 C 函数的可变参数是否安全?
Is it safe to completely ignore variadic arguments to a C function?
我有一个大致如下所示的函数:
typedef struct SomeType {
...
} SomeType;
void TakesArgs(SomeType *t1, ...) {
// iterates through arguments
}
// usage:
TakesArgs(&a, &b, &c);
如果我将 TakesArgs
更改为空操作,同时仍然保持所有调用代码不变,我 运行 是否会存在内存(或其他方面)的任何奇怪风险?
void TakesArgs(SomeType *t1, ...) {
return;
}
// usage unchanged:
TakesArgs(&a, &b, &c);
换句话说,跳过原实现中执行的va_list
/va_start
舞蹈会不会有什么奇怪的副作用?
是的,绝对安全。您不需要为了阅读而阅读所有可变参数。您甚至不需要在 TakesArgs
.
内启动可变参数读取序列
在幕后,它通常意味着执行任何参数传递维护任务的负担被赋予了调用代码(它们以通常被认为是 "traditional" C 调用约定的方式工作)。被叫方不需要做任何事情。
[根据评论进行编辑。]
有些系统默认弹出参数是被调用者的工作。那显然会给你带来麻烦。 但是,正是由于这个原因,必须正确声明可变参数函数,并且声明必须对调用者正确可见。原因是在那些系统上,可变参数函数必须使用调用者弹出参数的非默认调用序列,因为只有调用者才能确定有多少。所以只要你的函数被正确声明,你就应该是安全的。
我相信它是安全的,尽管标准在这一点上相当明确。
N1570 7.16 第 3 段说:
If access to the varying arguments is desired, the called function
shall declare an object (generally referred to as ap
in this
subclause) having type va_list
.
请注意该句子的开头:“If 需要访问不同的参数”。这意味着如果不需要访问不同的参数,则无需声明 va_list
对象——这将导致无法调用 va_start
、va_arg
或 va_end
.
一个可能的反驳是 va_end
(N1570 7.16.1.3) 的描述说:
If there is no corresponding invocation of the va_start
or va_copy
macro, or if the va_end
macro is not invoked before the return, the
behavior is undefined.
但是,考虑到上下文,我认为如果 va_end
未被调用 在 va_start
被调用后适用 。
我有一个大致如下所示的函数:
typedef struct SomeType {
...
} SomeType;
void TakesArgs(SomeType *t1, ...) {
// iterates through arguments
}
// usage:
TakesArgs(&a, &b, &c);
如果我将 TakesArgs
更改为空操作,同时仍然保持所有调用代码不变,我 运行 是否会存在内存(或其他方面)的任何奇怪风险?
void TakesArgs(SomeType *t1, ...) {
return;
}
// usage unchanged:
TakesArgs(&a, &b, &c);
换句话说,跳过原实现中执行的va_list
/va_start
舞蹈会不会有什么奇怪的副作用?
是的,绝对安全。您不需要为了阅读而阅读所有可变参数。您甚至不需要在 TakesArgs
.
在幕后,它通常意味着执行任何参数传递维护任务的负担被赋予了调用代码(它们以通常被认为是 "traditional" C 调用约定的方式工作)。被叫方不需要做任何事情。
[根据评论进行编辑。]
有些系统默认弹出参数是被调用者的工作。那显然会给你带来麻烦。 但是,正是由于这个原因,必须正确声明可变参数函数,并且声明必须对调用者正确可见。原因是在那些系统上,可变参数函数必须使用调用者弹出参数的非默认调用序列,因为只有调用者才能确定有多少。所以只要你的函数被正确声明,你就应该是安全的。
我相信它是安全的,尽管标准在这一点上相当明确。
N1570 7.16 第 3 段说:
If access to the varying arguments is desired, the called function shall declare an object (generally referred to as
ap
in this subclause) having typeva_list
.
请注意该句子的开头:“If 需要访问不同的参数”。这意味着如果不需要访问不同的参数,则无需声明 va_list
对象——这将导致无法调用 va_start
、va_arg
或 va_end
.
一个可能的反驳是 va_end
(N1570 7.16.1.3) 的描述说:
If there is no corresponding invocation of the
va_start
orva_copy
macro, or if theva_end
macro is not invoked before the return, the behavior is undefined.
但是,考虑到上下文,我认为如果 va_end
未被调用 在 va_start
被调用后适用 。