2012-02-15 3 views
0

Я получаю следующее предупреждение при попытке скомпилировать код:Предупреждение о компиляции GCC: формат '% i' ожидает аргумент типа 'int *', но аргумент 2 имеет тип 'enum month *' [-Wformat]

program141.c: 13: 5: предупреждение: формат '% я' ожидает аргумент типа 'INT *', но аргумент 2 имеет тип "перечисление месяц * [-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; 
} 

Этот код из книги, которую я читаю.

Как исправить это предупреждение?

ответ

2

Try с:

scanf ("%u", &aMonth); 
+1

Спасибо, это исправлено. –

+0

работает только до тех пор, пока никто не компилируется с '-fshort-enums', который по умолчанию включен на некоторых платформах. – Christoph

+0

Я согласен с Кристофом. Ранее ваш код предполагал, что enum является int, теперь он предполагает, что он является беззнаковым, но оба предположения нестабильны и не переносятся. Вы должны sscanf в int или unsigned, проверку диапазона, а затем назначьте перечисление. –

2

Input int, чем назначить его enum month объекта

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

Или вы можете попробовать бросок, но это не безопасно (представление enum и int s не обязательно быть одинаковыми)

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

Примечание: спецификатор формата "%i" принимает значения в десятичной, шестнадцатеричной и восьмеричной нотации.

4

Спецификация преобразования %i, используемая с функцией scanf, соответствует указателю на целое число со знаком. В C перечисляемый тип представляет собой целочисленный тип реализации, совместимый с этим типом.

В gcc перечисления обычно имеют тип unsigned int и типа int, если в константах перечисления есть отрицательное значение.

См gcc реализации определенной документации по перечислений (курсив мой):

В целочисленный тип, совместимый с каждым перечисляемого типа (C90 6.5.2.2, 6.7.2.2 C99).

Как правило, тип unsigned int, если в перечислении нет отрицательных значений, иначе int. Если указано -fshort-enums, то, если есть отрицательные значения, это первый из подписанных символов 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); 
+0

Приобретено. Спасибо за объяснение. –

+0

«В gcc, перечисления обычно имеют тип unsigned int» - поэтому ваш код будет «нормально» работать на gcc. Но не всегда. Downvoted, потому что мы можем делать лучше, чем «нормально». –

2

типа, лежащий в основе конкретного перечисления ISN 't обязательно int - реализации могут выбирать меньший тип, если все значения соответствуют (gcc сделает это, если вы включите -fshort-enums).

Для портативного решения сделайте aMonth a int (любой другой целочисленный тип будет работать до тех пор, пока вы используете правильный спецификатор преобразования) и при необходимости добавьте к enum month.

Смежные вопросы

 Смежные вопросы