在c函数中是否始终需要返回语句?

时间:2016-03-31 05:43:48

标签: c gcc

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语句吗?上述函数抛出以下警告。请注意,我没有return语句。

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))

2 个答案:

答案 0 :(得分:4)

不需要退货声明。

如果您的函数具有非void返回类型,并且您没有返回值,并且调用者使用返回值,则会导致未定义的行为。

编译器发出警告,因为你的函数有一个非void返回类型,并且它认为你可能想要返回一个但是被遗忘的值。

您发布的代码与编译器消息不对应,除非将PUBLIC定义为奇怪的内容。

答案 1 :(得分:0)

如果函数的返回类型不是void,您将始终收到警告。

如果要停止执行void类型函数(即使仍有可能要执行的指令),请使用return;

希望我帮忙!