gpt4 book ai didi

c - 在具有可变参数的函数中传递 "enum"时出错

转载 作者:行者123 更新时间:2023-12-01 16:19:05 33 4
gpt4 key购买 nike

我正在阅读《Head First C》这本书,我是关于变量参数的部分。

我写了下面的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

enum drink {
MUDSLIDE, FUZZY_NAVEL, MONKEY_GLAND, ZOMBIE
};

double price(enum drink d) {
switch(d) {
case MUDSLIDE:
return 6.79;
case FUZZY_NAVEL:
return 5.31;
case MONKEY_GLAND:
return 4.82;
case ZOMBIE:
return 5.89;
}
return 0;
}

double calc(int args, ...) {
double total = 0;

va_list ap;
va_start(ap, args);

int i;
for (i = 0; i < args; i++) {
int currentDrink = va_arg(ap, int);
total += price((drink) currentDrink);
}

va_end(ap);
return total;
}

int main() {
printf("Price is %.2f\n", calc(2, MONKEY_GLAND, MUDSLIDE));
return 0;
}

代码可以完美编译和运行。

但是...我的解决方案有两条不同的路线。

我的:

int currentDrink = va_arg(ap, int);
total += price((drink) currentDrink);

书:

enum drink currentDrink = va_arg(ap, enum drink);
total += price(currentDrink);

我尝试使用书中提出的解决方案,但在执行过程中出错并报告警告:'drink' is promote to 'int' when passed through '...'

本书使用的是linux上的gcc编译器。我在 Windows 上使用 gcc。

问题:我无法编译书中提出的代码的原因是什么?

编辑那里配置错了。正在使用 C++ 编译器正在考虑使用 C。但问题仍然存在:为什么在 C++ 中会导致执行时出现警告和错误?

最佳答案

函数的可变参数会受到称为默认参数提升的转换:转换级别小于 int 的所有内容都会提升为 int 在传递给可变参数函数之前。并且 enum 具有较小的转换等级(在您的情况下可能表示为 short 或其他内容)。所以你的被调用者看到的是一个 int 并且必须通过 va_arg 来获取它。

C99 7.15.1.1 p.2(强调我的)关于 va_arg:

[…] If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:

  • one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
  • [sth. about pointer types]

和 6.7.2.2, p.4:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, […]

因此,va_arg(ap, enum drink) 版本没有定义行为(就 C 标准而言)。至少,如果编译器没有指定始终对 enum 使用 int。因此来自 gcc 的警告。

一些编码指南说要完全避免对类型使用 enum,到处使用 int 并且只定义 enum 常量:

enum {
MUDSLIDE, FUZZY_NAVEL, MONKEY_GLAND, ZOMBIE
};

double price(int d);

HTH

关于c - 在具有可变参数的函数中传递 "enum"时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24580503/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com