在带有可变参数的函数中传递“枚举”时出错

猕猴

我正在阅读《 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”会提升为“ int”

本书用于Linux上的gcc编译器。我在Windows上使用gcc。

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

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

黑手党

函数的可变参数要进行称为默认参数提升的转换:转换级别小于传递给可变函数之前int被提升为的所有东西int并且enum转换等级较小(short在您的情况下,可以用表示)。因此,您的被呼叫者看到的是一个int,必须这样来获取它va_arg

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

[…]如果没有实际的下一个自变量,或者类型与实际的下一个自变量的类型不兼容(根据默认自变量Promotions的提升),则该行为是不确定的,除了以下情况:

  • 一种类型是有符号整数类型,另一种类型是相应的无符号整数类型,并且值在两种类型中都可以表示;
  • [某事。关于指针类型]

6.7.2.2,第4页:

每个枚举类型应与char,有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,[…]

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

一些编码准则说,要避免enum完全使用类型,而要int在各处使用并且仅定义enum常量:

enum {
    MUDSLIDE, FUZZY_NAVEL, MONKEY_GLAND, ZOMBIE
};

double price(int d);

高温超导

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当将带有 void * 参数的函数传递给 dict 时,Cython 会抛出错误

来自分类Dev

JS中带有参数传递的函数

来自分类Dev

传递带有不确定数量的参数的函数,并使用可变参数调用它

来自分类Dev

声明带有可变参数的函数指针

来自分类Dev

声明带有可变参数的函数指针

来自分类Dev

使用带有可变参数的函数的问题

来自分类Dev

将在构造函数中作为参数传递的函数指针分配给私有实例变量时出错

来自分类Dev

将参数传递给可变参数函数时,强制转换为void *有什么作用?

来自分类Dev

将枚举作为函数中的参数传递

来自分类Dev

传递带有参数作为参数的函数

来自分类Dev

在D中传递带有泛型参数的函数指针

来自分类Dev

在C ++ 11中传递带有未指定参数的函数?

来自分类Dev

如何在python中传递带有参数的函数?

来自分类Dev

在lldb中使用匿名枚举作为函数参数时出错

来自分类Dev

在lldb中使用匿名枚举作为函数参数时出错

来自分类Dev

带有部分参数包的可变参数帮助函数

来自分类Dev

带有可变参数模板参数的重载函数

来自分类Dev

将参数传递给C中的可变参数函数

来自分类Dev

在播放框架中传递参数时出错

来自分类Dev

传递带有设定参数的函数

来自分类Dev

Swift-如何在函数的参数中传递带有参数的函数?

来自分类Dev

如何或可以将带有参数作为参数的函数传递给lua中的函数?

来自分类Dev

Swift-如何在函数的参数中传递带有参数的函数?

来自分类Dev

如何在Boost Python中公开带有可变参数的C ++函数

来自分类Dev

如何在Boost Python中公开带有可变参数的C ++函数

来自分类Dev

传递参数时出错

来自分类Dev

传递参数时出错

来自分类Dev

将函数中的参数传递给DiagrammeR中的GrViz时出错:“找不到对象”

来自分类Dev

将函数中的参数传递给DiagrammeR中的GrViz时出错:“找不到对象”

Related 相关文章

  1. 1

    当将带有 void * 参数的函数传递给 dict 时,Cython 会抛出错误

  2. 2

    JS中带有参数传递的函数

  3. 3

    传递带有不确定数量的参数的函数,并使用可变参数调用它

  4. 4

    声明带有可变参数的函数指针

  5. 5

    声明带有可变参数的函数指针

  6. 6

    使用带有可变参数的函数的问题

  7. 7

    将在构造函数中作为参数传递的函数指针分配给私有实例变量时出错

  8. 8

    将参数传递给可变参数函数时,强制转换为void *有什么作用?

  9. 9

    将枚举作为函数中的参数传递

  10. 10

    传递带有参数作为参数的函数

  11. 11

    在D中传递带有泛型参数的函数指针

  12. 12

    在C ++ 11中传递带有未指定参数的函数?

  13. 13

    如何在python中传递带有参数的函数?

  14. 14

    在lldb中使用匿名枚举作为函数参数时出错

  15. 15

    在lldb中使用匿名枚举作为函数参数时出错

  16. 16

    带有部分参数包的可变参数帮助函数

  17. 17

    带有可变参数模板参数的重载函数

  18. 18

    将参数传递给C中的可变参数函数

  19. 19

    在播放框架中传递参数时出错

  20. 20

    传递带有设定参数的函数

  21. 21

    Swift-如何在函数的参数中传递带有参数的函数?

  22. 22

    如何或可以将带有参数作为参数的函数传递给lua中的函数?

  23. 23

    Swift-如何在函数的参数中传递带有参数的函数?

  24. 24

    如何在Boost Python中公开带有可变参数的C ++函数

  25. 25

    如何在Boost Python中公开带有可变参数的C ++函数

  26. 26

    传递参数时出错

  27. 27

    传递参数时出错

  28. 28

    将函数中的参数传递给DiagrammeR中的GrViz时出错:“找不到对象”

  29. 29

    将函数中的参数传递给DiagrammeR中的GrViz时出错:“找不到对象”

热门标签

归档