具有double类型的变量参数的函数的奇怪输出

Strange output for function with variable number parameters of type double

本文关键字:输出 函数 变量 double 类型 具有 参数      更新时间:2023-10-16

我尝试了使用可变数量整数参数的函数,它按预期工作。但当我尝试可变数量的"double"类型的参数时,它给出了奇怪的输出:

$ g++ -fpermissive -std=c++11 te2d.cc
te2d.cc: In function ‘void maxof(double, long int, ...)’:
te2d.cc:19:16: warning: return-statement with a value, in function returning 'void' [-fpermissive]
$ ./a.out
dum=100.200000
debug 1 0.000000
debug 2 0.000000
debug 3 -5486124068793688683255936251187209270074392635932332070112001988456197381759672947165175699536362793613284725337872111744958183862744647903224103718245670299614498700710006264535590197791934024641512541262359795191593953928908168990292758500391456212260452596575509589842140073806143686060649302051520512.000000
debug 4 0.000000

这是短代码:

#include <stdio.h>
#include <stdarg.h>
typedef unsigned char uchar;
typedef unsigned short uint16;
using namespace std;
typedef unsigned char uchar;
void maxof(double dum, long n_args, ...){
        printf("dum=%fn", dum);
        register int i;
        int max = 0;
        va_list ap;
        va_start(ap, n_args);
        for(i = 1; i <= n_args; i++) {
            printf("debug %d %fn", i, va_arg(ap, double));
        }
        va_end(ap);
        return max;
}
int main(int argc, char *argv[]) {
    maxof(100.2, 4, 10,14,13,11);
    return 0;
}

有什么想法吗?谢谢

C变元函数不能神奇地处理从intdouble*的转换。您需要指定进入函数的类型,而不是转换后要使用的类型。可以把它看作是告诉编译器如何与堆栈交互。如果你告诉它堆栈的顶部有一个double,而doubleint大,那么你现在只告诉它从堆栈中去掉额外的字节,这太可怕了。即使它们的大小相同,它们也没有相同的二进制表示。

你真的必须小心使用C变量函数。如果可用的话,更好的解决方案是使用可变模板,这是完全类型安全的,并触发编译时错误,而不是未定义的行为。在这种情况下,由于您希望所有参数都是相同的类型,因此可以使用std::initializer_list:

#include <initializer_list> //be sure not to forget this when using std::initializer_list
double maxof(std::initializer_list<double> nums) {
    double max = 0; //hope you don't have negative numbers
    for (const auto &num : nums) {
        if (num > max) {max = num;}
    }
    return max;
}
...
maxof({10,14,13,11})

请注意,有一个std::max的重载可以做到这一点,所以不需要编写自己的。

如果你一直使用C++11之前的版本,你可能会创建许多重载来获得同样的效果,但你最好创建一个基于容器或迭代器的函数,比如std::max_element


*Promotion应用于参数,因此它并不总是确切的类型。例如,传入char将需要函数提取int。这些促销活动都有很好的规定,主要是<small integral type>->int