简体   繁体   English

C 带返回值的 void 函数

[英]C void function with return value

As far as I know, return statement in void function will throw an error.据我所知,void 函数中的return语句会抛出错误。

But in the below program that is not the case.但在下面的程序中,情况并非如此。

Here the displayed output is 1 .这里显示的输出是1 How comes?怎么会?

main()
{
    int i=5;
    printf("%d",fun(fun(fun(i))));
}

void fun(int i)
{
    if (i%2)
    {
        return (i+(7*4)-(5/2)+(2*2));
    }
    else
    {
        return (i+(17/5)-(34/15)+(5/2));
    }
}

A return statement with no expression:没有表达式的return语句:

void func(void) {
    return;
}

is perfectly legal in a void function.void函数中是完全合法的。 The legality of a return statement with an expression depends on the version of the C language you're using.带有表达式的return语句的合法性取决于您使用的 C 语言版本。

The 1990 C standard says: 1990 C 标准说:

A return statement with an expression shall not appear in a function whose return type is void .带有表达式的return语句不应出现在返回类型为void的函数中。

The 1999 and 2011 editions of the standard both say:该标准的 1999 年和 2011 年版本都说:

A return statement with an expression shall not appear in a function whose return type is void .带有表达式的return语句不应出现在返回类型为void的函数中。 A return statement without an expression shall only appear in a function whose return type is void .没有表达式的return语句只能出现在返回类型为void的函数中。

This is a constraint , meaning that a compiler must issue a diagnostic (possibly a non-fatal warning) for any program that violates it.这是一个约束,意味着编译器必须为任何违反它的程序发出诊断(可能是非致命警告)。

C90 permitted a return statement with no expression in a non- void function for historical reasons.由于历史原因,C90 允许在非void函数中使用没有表达式的return语句。 Pre-ANSI C did not have the void keyword, so there was no way to define a function that didn't return a value. Pre-ANSI C 没有void关键字,因此无法定义不返回值的函数。 Programmers would omit the return type (which would default to int ) and simply ignore it.程序员会省略返回类型(默认为int )并简单地忽略它。 The C90 rule allowed such old code to compile without error. C90 规则允许这样的旧代码编译而不会出错。 You could still fail to return a value from a non- void function;您仍然可能无法从非void函数返回值; the program's behavior is undefined if a caller attempts to use the (nonexistent) result.如果调用者尝试使用(不存在的)结果,则程序的行为是未定义的。 The 1999 standard tightened up the rules a bit. 1999 年的标准稍微收紧了规则。

Another problem with your program is that you call fun before its declaration is visible.你的程序的另一个问题是你在它的声明可见之前调用了fun Under C99 and later rules, this is illegal (though a compiler might merely warn about it).根据 C99 和更高版本的规则,这是非法的(尽管编译器可能只是对此发出警告)。 Under C90 rules, this is legal, but the compiler will assume that the function returns int .在 C90 规则下,这是合法的,但编译器会假设函数返回int Your program's behavior is undefined, but your void function fun might happen to behave as if it returned a value, and a call to it might happen to behave as if it used that value.您的程序的行为是未定义的,但您的void函数fun可能恰好表现得好像它返回了一个值,而对它的调用可能恰好表现得好像它使用了该值。

C compilers tend to be fairly lax about some errors, so that old code (sometimes written before the first actual standard was published) will not be rejected. C 编译器往往对某些错误相当宽松,因此不会拒绝旧代码(有时在第一个实际标准发布之前编写)。 But your compiler should have at least warned you about the return statement, and probably about the invalid call.但是您的编译器至少应该警告您有关return语句的信息,以及可能有关无效调用的信息。 You should pay close attention to compiler warnings;您应该密切注意编译器警告; they should be treated almost the same way as fatal errors.应该像对待致命错误一样对待它们。 And you should use options to increase the number of things your compiler warns you about.并且您应该使用选项来增加编译器警告您的事情的数量。 If you're using gcc, use -std=c90 , -std=c99 , or -std=c11 , along with -pedantic to enforce standard conformance.如果您使用 gcc,请使用-std=c90-std=c99-std=c11以及-pedantic来强制执行标准一致性。 You can add -Wall -Wextra` to enable more warnings.您可以添加-Wall -Wextra 以启用更多警告。

The code you've presented is actually invalid in C99 for a variety of reasons, but the most painful one is below:由于各种原因,您提供的代码实际上在 C99 中无效,但最痛苦的一个如下:

foo.c:5:17: warning: implicit declaration of function 'fun' is invalid in C99 [-Wimplicit-function-declaration]
    printf("%d",fun(fun(fun(i))));
                ^
foo.c:8:6: error: conflicting types for 'fun'
void fun(int i)
     ^
foo.c:5:17: note: previous implicit declaration is here
    printf("%d",fun(fun(fun(i))));
                ^

Note that if you gave a function prototype for fun() , which you really should, then you would get a different set of errors:请注意,如果您为fun()提供了一个函数原型,您确实应该这样做,那么您将得到一组不同的错误:

foo.c:7:25: error: passing 'void' to parameter of incompatible type 'int'
    printf("%d",fun(fun(fun(i))));
                        ^~~~~~

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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