繁体   English   中英

这是使用带指针功能的va_arg的正确方法吗?

[英]Is this the correct way to use va_arg with pointer to function?

在这样的函数中:

typedef double(*dfun)(double);

void tab(double x, int n, ...)
{
    va_list args;

    va_start(args, n);

    printf("%5.2lf  \t", x);

    for (int i=0; i<n; i++)
    {
        dfun tmp = va_arg(args, dfun);

        printf("  %5.2lf  \t", tmp(x));
    }

    va_end(args);
}

如果我拉这样的论点是错的:

    double(*tmp)(double) = va_arg(args, double(*)(double));

我发现这篇文章提出了一种不同的方法,如果它不起作用:

问:我无法让va_arg引入类型指针到函数的参数。

答:尝试使用typedef作为函数指针类型。 va_arg宏通常播放的类型重写游戏受到过于复杂的类型(例如指向函数的指针)的阻碍。

在我的情况下,它适用于两个版本(GCC 5.2.1),这就是为什么我想知道一种方法比另一种更好? 当我没有首先将指针指向函数时,是否存在一些潜在的错误?

在某些情况下,使用不带typedef的指针确实会导致问题。

标准解释说, va_arg使用的type必须以某种方式编写,其中添加后缀*将创建指向type的指针:

7.16.1.1 va_arg宏

  1. 参数类型应该是指定的类型名称,以便只需通过将*固定为类型即可获得指向具有指定类型的对象的指针的类型

因此,要使用兼容代码,在使用函数指针时,应该使用typedef,因为*不能作为后缀添加到函数指针类型中以创建指向该类型的指针,因为语法无效:

(double)(*)(double) => (double)(*)(double)*

但它可以添加到typedef:

dfun => dfun*

va_arg(args, type)记录为(参见ISO 9899:2011§7.16.1.1¶2):

va_arg宏扩展为具有指定类型和调用中下一个参数值的表达式。 参数ap应该已经由va_startva_copy宏初始化(没有为同一个ap重新调用va_end宏)。 每次调用va_arg宏都会修改ap,以便依次返回连续参数的值。 参数类型应该是指定的类型名称,以便只需通过将*类型即可获得指向具有指定类型的对象的指针的类型 如果没有实际的下一个参数,或者type与实际的下一个参数的类型不兼容(根据默认参数提升而提升),则行为是未定义的,除了以下情况:

  • 一种类型是有符号整数类型,另一种类型是相应的无符号整数类型,并且该值可在两种类型中表示;
  • 一种类型是指向void的指针,另一种是指向字符类型的指针。

因此, va_arg(args, double(*)(double))不是va_args的有效调用,因为double(*)(double)*是语法错误而不是指向double(*)(double)的指针的类型将是double(**)(double) 因此,需要类型定义符合标准。 GNU C编译器是仁慈的,因为它不需要这种语法限制,但您的代码可能无法与其他编译器一起编译。

暂无
暂无

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

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