2016-03-31 3 views
2
PUBLIC void delset(set) 
SET *set; 
{ 
    /* Delete a set created with a previous newset() call. */ 

    if(set->map != set->defmap) 
     free(set->map); 
    free(set); 

} 

Вы всегда должны иметь оператор возврата в c-функции? Вышеуказанная функция выдает следующее предупреждение. Обратите внимание, что у меня нет оператора return.Является ли оператор возврата всегда необходимым в c-функции?

src/tools/set.c: In function ‘delset’: 
src/tools/set.c:41:1: warning: control reaches end of non-void function [-Wreturn-type] 
} 
^ 

После того, как я добавить return 0; предупреждение уходит. Я получаю предупреждение, даже если я просто указать return;

PUBLIC void delset(set) 
SET *set; 
{ 
    /* Delete a set created with a previous newset() call. */ 

    if(set->map != set->defmap) 
     free(set->map); 
    free(set); 

    return 0; 
} 

Я использую gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

Редактировать

# define PUBLIC

Похоже, это просто маркер. Это SO question, кажется, объясняет это лучше, чем я могу.

void delset(set) 
SET *set; 
{ 
    /* Delete a set created with a previous newset() call. */ 

    if(set->map != set->defmap) 
     free(set->map); 
    free(set);   
} 

Я удалил маркер PUBLIC перед функцией и обратную линию внизу. Я все равно получаю ту же ошибку.

typedef struct _set_ 
{ 
    unsigned char nwords;         /* Number of words in map */ 
    unsigned char compl;         /* is a negative true set if true */ 
    unsigned nbits;           /* Number of bits in map */ 
    _SETTYPE *map;           /* Pointer to the map */ 
    _SETTYPE defmap[ _DEFWORDS ];       /* The map itself */ 

} SET; 

Включение файла следующий заголовок (debug.h) была причиной проблемы. Не знаете, какая именно строка его вызывала.

#ifdef DEBUG 
# define PRIVATE 
# define D (x) x 
#else 
# define PRIVATE static 
# define D (x) 
#endif 
# define PUBLIC 

#ifdef MSDOS 
# define MS(x) x 
# define UX(x) 
# define ANSI 
# define _8086 
#else 
# define MS(x) 
# define UX(x) x 
# define O_BINARY 0 /*no binary input mode in UNIX open() */ 
    typedef long time_t; /* for the VAX, may have to change this */ 
    typedef unsigned s1ze_t; /* for the VAX, may have to change this. Renamed the type as s1ze_t as stdio.h contains a type of the same name */ 
    extern char *strdup(); /* You need to supply one. */ 
#endif 

#ifdef ANSI /* If ANSI is defined, put arg lists into */ 
# define P(x) x /* function prototypes. */ 
# define VA_LIST ... /* and use ellipsis if a variable number of args */ 
#else 
# define P(x)() /*Otherwise, discard argument lists and translate*/ 
# define void char /* void keyword to int. */ 
# define VA LIST _a_r_g_s /* don't use ellipsis */ 
#endif 

/* SEG (p) Evaluates to the segment portion of an 8086 address. 
* OFF (p) Evaluates to the offset portion of an 8086 address. 
* PHYS (p) Evaluates to a long holding a physical address 
*/ 

#ifdef _8086 
# define SEG(p) (((unsigned *)&(p)) [1]) 
# define OFF(p) (((unsigned *)&(p)) [0]) 
# define PHYS(p) (((unsigned long)OFF(p)) + ((unsigned long)SEG(p) << 4)) 
#else 
# define PHYS(p) (p) 
#endif 

/* NUMELE (array) Evaluates to the array size in elements 
* LASTELE(array) Evaluates to a pointer to the last element 
* INBOUNDS(array,p) Evaluates to true i f p points into the array. 
* RANGE(a,b,c) Evaluates to true i f a <= b <= c 
* max(a,b) Evaluates to a or b, whichever is larger 
* min (a, b) Evaluates to a or b, whichever is smaller 
* 
* NBITS (type) Returns number of bits in a variable of the indicated 
* type; 
* MAXINT Evaluates to the value of the largest signed integer 
*/ 

#define NUMELE(a)  (sizeof(a)/sizeof(*(a))) 
#define LASTELE(a)  ((a) + (NUMELE(a)-1)) 
#define TOOHIGH(a,p)  ((p) - (a) > (NUMELE(a) - 1)) 
#define TOOLOW(a,p)   ((p) - (a) < 0) 
#define INBOUNDS(a,p)  (!(TOOHIGH(a,p) || TOOLOW(a,p)) 

#define _IS(t, x) (((t)1 << (x)) != 0) /* Evaluate true if the width of a */ 
        /* variable of type of t is < x. The !=0 */ 
        /* assures that the answer is 1 or 0 */ 

#define NBITS(t) (4 * (1 + _IS(t, 4) + _IS(t, 8) + _IS(t,12) + _IS(t, 16) + _IS(t,20) + _IS(t,24) + _IS(t,28) + _IS(t,32)) 


#define MAXINT (((unsigned)~0) >> 1) 

#ifndef max 
# define max(a, b) (((a) > (b)) ? (a) : (b)) 
#endif 
#ifndef min 
# define min(a,b)  (((a) < (b)) ? (a) : (b)) 
#endif 
#define RANGE(a,b,c) ((a) <= (b) && (b) <= (c)) 
+12

Что такое 'PUBLIC'? – alk

+1

Как выглядит вывод перед процессором? – alk

+2

Это необходимо для функций, отличных от '' void'. Если вы не хотите, чтобы функция возвращала значение, объявите ее «void». Тогда управление может дойти до конца функции, не будучи ошибкой (и вы также можете использовать голые инструкции 'return'). Если функция не является '' void', тогда она всегда должна возвращать значение. –

ответ

4

Операция возврата не требуется.

Если ваша функция имеет невоенный тип возврата и вы не возвращаете значение, а вызывающий использует возвращаемое значение, то это вызывает неопределенное поведение.

Компилятор дает предупреждение, потому что ваша функция имеет невоенный тип возврата, и он думает, что вы, возможно, хотели вернуть значение, но забыли.

Код, который вы отправили, не соответствует сообщению компилятора, если только PUBLIC не является чем-то странным.

+0

Бьюсь об заклад, есть способ отключить предупреждение для этой функции, а не глобально. Таким образом, компилятор покажет мне предупреждение в других местах. Что-то вроде '@ SuppressWarnings' в java. – ShaggyInjun

+0

@ShaggyInjun исправление ошибки было бы лучше, чем подавление предупреждения. –

+0

Не уверен, что предупреждение появилось из 'PUBLIC'. Предупреждение все еще существует после того, как я удалил его и оператор return. – ShaggyInjun

0

Вы всегда получите предупреждение, если возвращаемый тип функции не является void.

Если вы хотите остановить выполнение функции типа void (даже если все еще могут выполняться инструкции), используйте return;.

Надеюсь, я помог!

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