[英]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 isvoid
.带有表达式的
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 isvoid
.带有表达式的
return
语句不应出现在返回类型为void
的函数中。 Areturn
statement without an expression shall only appear in a function whose return type isvoid
.没有表达式的
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.