简体   繁体   中英

Is a return statement always necessary in a c function?

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

}

Do you always have to have a return statement in a c function? The above function throws the following warning. Notice that I don't have a return statement.

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

Once I add the return 0; the warning goes away. I get the warning even if I just specify 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;
}

I am using gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

Edit

# define PUBLIC

Seems like it is just a marker. This SO question seems to explain it better than I can.

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

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

I removed the PUBLIC marker in front of the function and the return line at the bottom. I still get the same error.

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;

Inclusion of the following header file ( debug.h ) was causing the problem. Not sure which line exactly was causing it.

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

A return statement is not necessary.

If your function has a non-void return type, and you don't return a value, and the caller uses the return value, then it causes undefined behaviour.

The compiler gives a warning because your function has a non-void return type, and it thinks you might have meant to return a value but forgotten.

The code you posted doesn't correspond to the compiler message, unless PUBLIC is defined to something strange.

You will always get a warning if the return-type of a function is not void .

If you want to stop the execution of a void- type function (even though there still might be instructions to be executed) use return; .

Hope I helped !

It seems to me that you have some basic syntax misunderstandings, but if you just insert "void" before your function name (SET), the compiler will understand that the function returns nothing and the warning will be alleviated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM