在 C 和 C++ 中返回 void 类型
Posted
技术标签:
【中文标题】在 C 和 C++ 中返回 void 类型【英文标题】:Return void type in C and C++ 【发布时间】:2016-06-29 11:43:42 【问题描述】:编译时没有任何警告。
这在 C 和 C++ 中是合法的还是只在 gcc 和 clang 中有效?
如果是合法的,是不是C99之后的新东西?
void f()
void f2()
return f();
更新
正如“Rad Lexus”建议的那样,我尝试了这个:
$ gcc -Wall -Wpedantic -c x.c
x.c: In function ‘f2’:
x.c:7:9: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic]
return f();
$ clang -Wall -Wpedantic -c x.c
x.c:7:2: warning: void function 'f2' should not return void expression [-Wpedantic]
return f();
^ ~~~~~
1 warning generated.
$ gcc -Wall -Wpedantic -c x.cc
(no errors)
$ clang -Wall -Wpedantic -c x.cc
(no errors)
更新
有人问这种结构有什么帮助。好吧,或多或少是语法糖。这是一个很好的例子:
void error_report(const char *s)
printf("Error %s\n", s);
exit(0);
void process()
if (step1() == 0)
return error_report("Step 1");
switch(step2())
case 0: return error_report("Step 2 - No Memory");
case 1: return error_report("Step 2 - Internal Error");
printf("Processing Done!\n");
【问题讨论】:
投票重新开放;建议的副本仅适用于 C++。这也被标记为 C。(C 和 C++ 在使用void
方面有很大不同)。
所以你要的是 C 还是 C++?选择一种语言。
注意:使用gcc -Wall -Wpedantic -std=c99
和-std=c11
,您会收到警告:“警告:ISO C 禁止在函数返回 void [-Wpedantic] 中使用表达式'返回'”。
@HolyBlackCat:我可以同时询问 C、C++ 和 Java 吗? ;-)
@DevSolar :D 好吧,我会说得更清楚。 IMO 询问 C 和 C++ 中存在的功能是合法的。通常,这些功能在两种语言中的行为相似。如果不是,一个好的答案将描述差异。
【参考方案1】:
C11,6.8.6.4“return
声明”:
带有表达式的
return
语句不得出现在返回类型为void
的函数中。
不行,你不能使用表达式,即使它是void
类型。
来自同一文档的前言:
第二版的主要变化包括:
[...]
return
在返回值的函数中不允许没有表达式(反之亦然)
所以这是从 C89 -> C99(语言标准的第二版)的变化,从那以后一直如此。
C++14,6.6.3“return
语句”:
带有非 void 类型表达式的 return 语句只能用于返回值的函数 [...] 带有 void 类型表达式的 return 语句只能在返回类型为 cv 的函数中使用 空白;表达式在函数返回给它的调用者之前被计算。
是的,您可以使用表达式if它是 void 类型(从 C++98 开始就有效)。
【讨论】:
“带有 void 类型表达式的 return 语句只能在返回类型为 cv void 的函数中使用” 为什么有人想编写这样无意义的代码呢?而不仅仅是写void f2() f();
。似乎在某个地方一定有它的理由,即使它是 C++?
@Lundin:模板?我假设。看起来
@Lundin:在 C++ 中,主要用于模板。如果f
和f2
的返回类型是模板的参数,则无需特殊情况void
就可以编写return f();
很方便。 (显然,这个特定的示例代码并不能真正用作模板 - 但对于更复杂的代码,它可能很有用 - 例如,请参阅futures
的东西。
正如 Mohit 的回答正确引用的那样,“返回值的函数中不允许不带表达式的返回”项位于前言第 7 段“second 版中的重大变化”下,而不是第 6 段“这第三版...... [m]jor changes”。第二版是C99,将C89/90改成返回无表达式; void 函数中的 return with 表达式自 C89/90 以来被禁止,当时 void 首次引入。 C99 之前的@Lundin 在 non-void 函数中返回没有表达式并且尝试使用该值的调用者是 UB。
特别是在函数同步执行的情况下,成员只会return external_function(args...);
【参考方案2】:
此代码在C++
中允许,但在C
中不允许
来自Return statement @ cppreference
在返回void的函数中,带有表达式的return语句可以 如果表达式类型为 void,则使用。
C11 规范草案 n1570 中的 OTOH:
第二版的主要变化包括:
在返回 a 的函数中不允许不带表达式的返回 价值(反之亦然)
(return
的表达式不允许在返回 void
的函数中使用)
和 6.8.6.4 返回
带有表达式的return语句不应出现在函数中 其返回类型为 void。没有表达式的 return 语句 只能出现在返回类型为 void 的函数中。
(即使表达式的计算结果为void
)
【讨论】:
最好引用 C++ 标准和可能的文档,因为允许构造的版本。 cppreference 不是一个非常可靠的来源,许多代码示例都有错误。 @chqrlie 你能给我一个链接到代码示例正在拧@en.cppreference 的页面吗? @MohitJain:只是一个例子:en.cppreference.com/w/c/string/byte/strncat 用 gcc 4.6 编译:main.cpp:31:1: warning: control reaches end of non-void function [-Wreturn-type]
。自 C99 以来不是错误,但风格不好。
@chqrlie 谢谢。我没有 C++ 规范,我在需要时使用最新的草稿和 en.cppreference 供我参考。
@MohitJain:C++ 最新草案已经足够接近了。源代码实际上在 github 上可用!我希望 C 和 C++ 标准可以免费公开获得。 cppreference其实是有据可查的,我之前的判断可能反映了我对法语翻译的印象。任何可见的错误都可以在发现时进行修复。【参考方案3】:
C++ 允许这样的事情:
void f()
return void();
而 C 没有。这就是为什么如果您将其编译为 ISO C 而不是 ISO C++ 会发出警告。这正式描述为:
带有 void 类型表达式的 return 语句只能用于 返回类型为 cv void 的函数
【讨论】:
它看起来是正确的,但是两个声明的标准引用会很好。【参考方案4】:ISO/IEC 9899:201x 委员会草案规定如下:
6.8.6.4 返回语句
约束
return
带有表达式的语句不应出现在返回类型为void
的函数中。没有表达式的
return
语句只能出现在 返回类型为void
的函数。
所以,在 C 中是禁止的。
您需要使用-pedantic
切换到gcc
来投诉标准违规:
test.c: In function ‘f2’:
test.c:6:12: warning: ISO C forbids ‘return’ with expression, in function returning void
[-Wpedantic]
return f();
【讨论】:
【参考方案5】:标准 C 不支持这种结构:
C11 6.8.6.4:
return
声明约束
1 带有表达式的
return
语句不得出现在返回类型为void
的函数中。没有表达式的return
语句只能出现在返回类型为void
的函数中。
没有针对问题中的特殊情况添加特殊规定。一些 C 编译器确实支持此作为扩展(gcc
支持,除非被指示符合 C 标准之一),但 C11 和以前的版本认为它违反了约束。
【讨论】:
以上是关于在 C 和 C++ 中返回 void 类型的主要内容,如果未能解决你的问题,请参考以下文章