简体   繁体   English

已知数量的args,在c中转发可变参数函数

[英]With known number of args, forward variadic function in c

I am aware it is generally not possible to forward variadic arguments from one variadic function to another: Forward an invocation of a variadic function in C http://c-faq.com/varargs/handoff.html我知道通常不可能将可变参数从一个可变参数函数转发到另一个: Forward an invocation of a variadic function in C http://c-faq.com/varargs/handoff.html

My question is, is it possible if I know the number of variadic args in the callee?我的问题是,如果我知道被调用者中可变参数的数量,是否有可能? For example, can f_wrapper be written to pass ... arguments to f?:例如,是否可以编写 f_wrapper 以将 ... 参数传递给 f?:

int f_wrapper(int argc, ...){ 
  /* argc is the number of variadic args f_wrapper is called with. Can it be used to call f? */
  /* Example: f_wrapper(3, "arg1", "arg2", "arg3"); */
}
int f(...){
  /* f must be called with all ... args from f_wrapper. */
  /* Adding signature with va_list is NOT allowed. c++ is NOT allowed */
}

My question is, is it possible if I know the number of variadic args in the callee?我的问题是,如果我知道被调用者中可变参数的数量,是否有可能? For example, can f_wrapper be written to pass ... arguments to f?例如,是否可以编写 f_wrapper 以将 ... 参数传递给 f?

The basic problem is that forwarding variadic arguments from one variadic function to another is a lexical issue, not a data processing issue.基本问题是,将可变参数从一个可变参数函数转发到另一个是词汇问题,而不是数据处理问题。 You must write a call to the wrapped function in which there is a compile-time representation of each argument, but you don't know until run time how many there will be, and you might not know their types.您必须编写对包装函数的调用,其中每个参数都有一个编译时表示,但是直到运行时您才知道会有多少,并且您可能不知道它们的类型。

If the space of acceptable argument lists is constrained enough, then the problem is pragmatically solvable.如果可接受的参数列表的空间受到足够的限制,那么这个问题实际上是可以解决的。 For example, if the wrapper will permit only a small number of variadic arguments, of only a small number of types (that it knows how to recognize), then it can analyze the variadic arguments at runtime to match them to the appropriate one of a list of possible calls to the wrapped function.例如,如果包装器只允许少量可变参数,只允许少量类型(它知道如何识别),那么它可以在运行时分析可变参数以将它们匹配到适当的一个对包装函数的可能调用列表。 Something like this:像这样的东西:

int f_wrapper(int argc, ...) {
    if (argc < 0 || argc > F_ARGS_MAX) {
        // unsupported number of arguments
        return -1;
    }

    int arg_values[F_ARGS_MAX];
    // ... read argc variadic arguments into arg_values ...

    switch (argc) {
        case 0:
            return f();
        case 1:
            return f(arg_values[0]);
        // ...
    }
}

Obviously, however, that gets impractical rather quickly, and it can't cope at all if there is no upper bound on the acceptable number of arguments.然而,显然,这很快就变得不切实际,如果可接受的参数数量没有上限,它根本无法应对。

As was suggested in comments, a variadic macro may be a more viable alternative, but that's not a complete substitute.正如评论中所建议的那样,可变参数宏可能是一个更可行的替代方案,但这并不是一个完全的替代方案。 For example, you cannot construct a pointer to a macro, you cannot use such a macro to provide an external interface to a function with internal linkage, the macro cannot host a static variable in the same way that a function does, ....例如,您不能构造指向宏的指针,不能使用这样的宏为具有内部链接的函数提供外部接口,宏不能以与函数相同的方式承载静态变量,...。

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

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