GCC编译警告:格式‘%i’需要类型为“int *”的参数,但参数 2 的类型为“enum Month *” [-W格式]

发布于 2025-01-05 23:20:43 字数 1149 浏览 2 评论 0原文

当我尝试编译代码时收到以下警告:

program141.c:13:5: warning: format '%i' Expects argument of type 'int *', but argument 2 has type 'enum Month *' [-Wformat ]

// Program to print the number of days in a month

#include <stdio.h>

int main (void)
{
    enum month { january = 1, february, march, april, may, june,
         july, august, september, october, november, december };
    enum month aMonth;
    int        days;

    printf ("Enter month number: ");
    scanf ("%i", &aMonth);

    switch (aMonth) {
    case january:
    case march:
    case may:
    case july:
    case august:
    case october:
    case december:
        days = 31;
        break;
    case april:
    case june:
    case september:
    case november:
        days = 30;
        break;
    case february:
        days = 28;
        break;
    default:
        printf ("bad month number\n");
        days = 0;
        break;
    }

    if ( days != 0 )
    printf ("Number of days is %i\n", days);

    if ( aMonth == february )
    printf ("...or 29 if it's a leap year\n");

    return 0;
}

这段代码来自我正在读的一本书。

我该如何解决这个警告?

I get the following warning when I try to compile the code:

program141.c:13:5: warning: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘enum month *’ [-Wformat]

// Program to print the number of days in a month

#include <stdio.h>

int main (void)
{
    enum month { january = 1, february, march, april, may, june,
         july, august, september, october, november, december };
    enum month aMonth;
    int        days;

    printf ("Enter month number: ");
    scanf ("%i", &aMonth);

    switch (aMonth) {
    case january:
    case march:
    case may:
    case july:
    case august:
    case october:
    case december:
        days = 31;
        break;
    case april:
    case june:
    case september:
    case november:
        days = 30;
        break;
    case february:
        days = 28;
        break;
    default:
        printf ("bad month number\n");
        days = 0;
        break;
    }

    if ( days != 0 )
    printf ("Number of days is %i\n", days);

    if ( aMonth == february )
    printf ("...or 29 if it's a leap year\n");

    return 0;
}

This code is from a book I'm reading.

How do I fix this warning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

卖梦商人 2025-01-12 23:20:43

scanf 函数一起使用的 %i 转换规范与指向有符号整数的指针匹配。在 C 中,枚举类型是与该类型兼容的实现定义的整数类型。

在 gcc 中,枚举通常为 unsigned int 类型,如果枚举常量中有负值,则枚举为 int 类型。

请参阅关于枚举的 gcc 实现定义文档(重点是我的):

与每个枚举类型兼容的整数类型(C90 6.5.2.2、C99 6.7.2.2)。

通常,如果枚举中没有负值,则类型为unsigned int,否则为int。如果指定了-fshort-enums,则如果有负值,则为第一个可以表示所有值的signed char,short和int,否则为第一个可以表示所有值的unsigned char,unsigned Short和unsigned int价值观。
在某些目标上,-fshort-enums 是默认值;这是由 ABI 决定的。

来源 http://gcc.gnu.org/ onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

要修复系统上的警告,只需使用与指向无符号整数类型的指针匹配的 %u 转换规范:

scanf ("%u", &aMonth);

The %i conversion specification used with the scanf function matches a pointer to a signed integer. In C, an enumerated type is an implementation defined integer type compatible with that type.

In gcc, enums are normally of type unsigned int and of type int if there is a negative value in the enum constants.

See gcc implementation defined documentation on enums (emphasis mine):

The integer type compatible with each enumerated type (C90 6.5.2.2, C99 6.7.2.2).

Normally, the type is unsigned int if there are no negative values in the enumeration, otherwise int. If -fshort-enums is specified, then if there are negative values it is the first of signed char, short and int that can represent all the values, otherwise it is the first of unsigned char, unsigned short and unsigned int that can represent all the values.
On some targets, -fshort-enums is the default; this is determined by the ABI.

Source http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

To fix the warning on your system, just use the %u conversion specification that matches a pointer to an unsigned integer type:

scanf ("%u", &aMonth);
你的背包 2025-01-12 23:20:43

尝试使用:

scanf ("%u", &aMonth);

Try with:

scanf ("%u", &aMonth);
源来凯始玺欢你 2025-01-12 23:20:43

输入一个int,然后将其分配给enum Month对象

int temp;
scanf("%d", &temp);
/* make sure 1 <= temp <= 12 */
aMonth = temp;


或者您可以尝试强制转换,但它并不安全(enum 和 int 的表示不必相同) s>

scanf("%d", (int*)&aMonth);

注意:格式说明符"%i"接受十进制、十六进制和八进制表示法的值。

Input an int, than assign it to the enum month object

int temp;
scanf("%d", &temp);
/* make sure 1 <= temp <= 12 */
aMonth = temp;


Or you can try a cast, but it is not safe (the representation of the enum and ints need not be the same)

scanf("%d", (int*)&aMonth);

Note: the format specifier "%i" accepts values in decimal, hexadecimal, and octal notations.

め可乐爱微笑 2025-01-12 23:20:43

特定枚举的底层类型不一定是 int - 只要所有值都适合,实现就可以自由选择较小的类型(如果启用 -fshort-enums,gcc 将执行此操作)代码>)。

对于可移植的解决方案,请将 aMonth 设为 int(只要使用正确的转换说明符,任何其他整数类型都可以)并转换为 enum Month 根据需要。

The type underlying a particular enumeration isn't necessarily int - implementations are free to choose a smaller type as long as all values fit (gcc will do this if you enable -fshort-enums).

For a portable solution, make aMonth an int (any other integer type will do as long as you use the correct conversion specifier) and cast to enum month as necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文