为什么将未使用的返回值转换为 void?

发布于 2024-07-15 08:09:46 字数 120 浏览 7 评论 0原文

int fn();

void whatever()
{
    (void) fn();
}

是否有任何理由将未使用的返回值强制转换为 void,或者我认为这完全是浪费时间?

int fn();

void whatever()
{
    (void) fn();
}

Is there any reason for casting an unused return value to void, or am I right in thinking it's a complete waste of time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

救星 2024-07-22 08:09:46

大卫的答案几乎涵盖了这样做的动机,明确地向其他“开发人员”表明您知道此函数返回但您明确忽略它。

这是一种确保始终处理必要的错误代码的方法。

我认为对于 C++,这可能是我也更喜欢使用 C 风格强制转换的唯一地方,因为在这里使用完整的静态强制转换表示法感觉有点矫枉过正。 最后,如果您正在审查或编写编码标准,那么明确声明对重载运算符(不使用函数调用表示法)的调用也应该免除这一点也是一个好主意:

class A {};
A operator+(A const &, A const &);

int main () {
  A a;
  a + a;                 // Not a problem
  (void)operator+(a,a);  // Using function call notation - so add the cast.

David's answer pretty much covers the motivation for this, to explicitly show other "developers" that you know this function returns but you're explicitly ignoring it.

This is a way to ensure that where necessary error codes are always handled.

I think for C++ this is probably the only place that I prefer to use C-style casts too, since using the full static cast notation just feels like overkill here. Finally, if you're reviewing a coding standard or writing one, then it's also a good idea to explicitly state that calls to overloaded operators (not using function call notation) should be exempt from this too:

class A {};
A operator+(A const &, A const &);

int main () {
  A a;
  a + a;                 // Not a problem
  (void)operator+(a,a);  // Using function call notation - so add the cast.
千纸鹤带着心事 2024-07-22 08:09:46

在工作中,我们用它来确认该函数有返回值,但开发人员断言忽略它是安全的。 由于您将问题标记为 C++,因此您应该使用static_cast

static_cast<void>(fn());

就编译器而言,将返回值强制转换为 void 没有什么意义。

At work we use that to acknowledge that the function has a return value but the developer has asserted that it is safe to ignore it. Since you tagged the question as C++ you should be using static_cast:

static_cast<void>(fn());

As far as the compiler goes casting the return value to void has little meaning.

深爱不及久伴 2024-07-22 08:09:46

这样做的真正原因可以追溯到 C 代码上使用的工具,称为 lint

它分析代码寻找可能的问题并发出警告和建议。 如果函数返回的值随后未被检查,lint 会发出警告,以防这是意外情况。 要消除此警告的 lint,请将调用强制转换为 (void)

The true reason for doing this dates back to a tool used on C code, called lint.

It analyzes code looking for possible problems and issuing warnings and suggestions. If a function returned a value which was then not checked, lint would warn in case this was accidental. To silence lint on this warning, you cast the call to (void).

王权女流氓 2024-07-22 08:09:46

转换为 void 用于抑制编译器对未使用的变量和未保存的返回值或表达式发出警告。

标准(2003)在§5.2.9/4 中说,

任何表达式都可以显式转换为类型“cv void”。 表达式值被丢弃

所以你可以写:

//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);

//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());

//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());

所有形式都是有效的。 我通常将其缩短为:

//suppressing  expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);

也可以。

Casting to void is used to suppress compiler warnings for unused variables and unsaved return values or expressions.

The Standard(2003) says in §5.2.9/4 says,

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.

So you can write :

//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);

//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());

//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());

All forms are valid. I usually make it shorter as:

//suppressing  expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);

Its also okay.

只涨不跌 2024-07-22 08:09:46

C++17 或更高版本

[[maybe_unused]] auto unused = fn();

C++11 或更高版本

更新:不建议使用此方法,因为它可能会在规范的未来版本中出现问题。请参阅这篇文章进行更多讨论。

从 C++11 开始,您还可以这样做:

std::ignore = fn();

这应该在标有 [[nodiscard]] 的函数上实现相同的结果

C++17 or greater

[[maybe_unused]] auto unused = fn();

C++11 or greater

Update: this approach is not recommended as it could potentially break in future version of the spec. See this post for more discussion.

As of C++11 you can also do:

std::ignore = fn();

This should achieve the same result on functions marked with [[nodiscard]]

如果没结果 2024-07-22 08:09:46

从 c++17 开始,我们有了 [[maybe_unused]] 属性,可以使用它来代替 void 强制转换。

Since c++17 we have the [[maybe_unused]] attribute which can be used instead of the void cast.

花开雨落又逢春i 2024-07-22 08:09:46

施放至虚空是无成本的。 它只是编译器如何处理它的信息。

Cast to void is costless. It is only information for compiler how to treat it.

〗斷ホ乔殘χμё〖 2024-07-22 08:09:46

对于你的程序功能来说,强制转换为 void 是没有意义的。 我还认为,正如大卫的回答所建议的那样,您不应该使用它来向正在阅读代码的人发出某些信号。 如果您想传达您的意图,最好使用评论。 添加这样的演员表只会看起来很奇怪,并会引发对其可能原因的疑问。 只是我的观点...

For the functionality of you program casting to void is meaningless. I would also argue that you should not use it to signal something to the person that is reading the code, as suggested in the answer by David. If you want to communicate something about your intentions, it is better to use a comment. Adding a cast like this will only look strange and raise questions about the possible reason. Just my opinion...

终陌 2024-07-22 08:09:46

C++17 [[nodiscard]]

C++17用一个属性标准化了“返回值忽略的业务”。

因此,我希望兼容的实现始终仅在给出 nodiscard 时发出警告,否则永远不会发出警告。

示例:

main.cpp

[[nodiscard]] int f() {
    return 1;
}

int main() {
    f();
}

编译:

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp

结果:

main.cpp: In function ‘int main()’:
main.cpp:6:6: warning: ignoring return value of ‘int f()’, declared with attribute nodiscard [-Wunused-result]
    6 |     f();
      |     ~^~
main.cpp:1:19: note: declared here
    1 | [[nodiscard]] int f() {
      | 

以下所有内容都避免了警告:

(void)f();
[[maybe_unused]] int i = f();

我无法直接在 f() 调用上使用 maybe_unused: 给出

[[maybe_unused]] f();

main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
    6 |     [[maybe_unused]] f();
      |     ^~~~~~~~~~~~~~~~

< code>(void) 强制转换工作似乎不是强制性的,但在标准中是“鼓励”的:如何故意丢弃 [[nodiscard]] 返回值?

另外从警告消息中可以看出,警告的一个“解决方案”是添加 -Wno-unused-result

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp

尽管我当然不会建议像这样全局忽略警告。

C++20 还允许您向 nodiscard 添加原因,如 [[nodiscard("reason")]] 中所述,如:https://en.cppreference.com/w/cpp/language/attributes/nodiscard

< strong>GCC warn_unused_result attribute

[[nodiscard]] 标准化之前,对于 C 最终决定标准化属性之前,GCC 实现了完全相同的功能与 warn_unused_result:

int f() __attribute__ ((warn_unused_result));

int f() {
    return 1;
}

int main() {
    f();
}

给出:

main.cpp: In function ‘int main()’:
main.cpp:8:6: warning: ignoring return value of ‘int f()’, declared with attribute warn_unused_result [-Wunused-result]
    8 |     f();
      |     ~^~

应该注意的是,由于 ANSI C 没有这方面的标准,ANSI C 没有指定哪些 C 标准库函数具有或不具有该属性,因此实现具有他们自己决定什么应该或不应该用 warn_unuesd_result 标记,这就是为什么通常您必须使用 (void) 转换来忽略任何调用的返回标准库函数可以完全避免任何实现中的警告。

在 GCC 9.2.1、Ubuntu 19.10 中测试。

C++17 [[nodiscard]]

C++17 standardized the "return value ignored business" with an attribute.

Therefore, I hope that compliant implementations will always warn only when nodiscard is given, and never warn otherwise.

Example:

main.cpp

[[nodiscard]] int f() {
    return 1;
}

int main() {
    f();
}

compile:

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp

outcome:

main.cpp: In function ‘int main()’:
main.cpp:6:6: warning: ignoring return value of ‘int f()’, declared with attribute nodiscard [-Wunused-result]
    6 |     f();
      |     ~^~
main.cpp:1:19: note: declared here
    1 | [[nodiscard]] int f() {
      | 

The following all avoid the warning:

(void)f();
[[maybe_unused]] int i = f();

I wasn't able to use maybe_unused directly on the f() call:

[[maybe_unused]] f();

gives:

main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
    6 |     [[maybe_unused]] f();
      |     ^~~~~~~~~~~~~~~~

The (void) cast working does not appear to be mandatory but is "encouraged" in the standard: How can I intentionally discard a [[nodiscard]] return value?

Also as seen from the warning message, one "solution" to the warning is to add -Wno-unused-result:

g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp

although I wouldn't of course recommend ignoring warnings globally like this.

C++20 also allows you to add a reason to the nodiscard as in [[nodiscard("reason")]] as mentioned at: https://en.cppreference.com/w/cpp/language/attributes/nodiscard

GCC warn_unused_result attribute

Before the standardization of [[nodiscard]], and for C before they finally decide to standardize attributes, GCC implemented the exact same functionality with the warn_unused_result:

int f() __attribute__ ((warn_unused_result));

int f() {
    return 1;
}

int main() {
    f();
}

which gives:

main.cpp: In function ‘int main()’:
main.cpp:8:6: warning: ignoring return value of ‘int f()’, declared with attribute warn_unused_result [-Wunused-result]
    8 |     f();
      |     ~^~

It should be noted then that since ANSI C does not have a standard for this, ANSI C does not specify which C standard library functions have the attribute or not and therefore implementations have made their own decisions on what should or not be marked with warn_unuesd_result, which is why in general you would have to use the (void) cast to ignore returns of any calls to standard library functions to fully avoid warnings in any implementation.

Tested in GCC 9.2.1, Ubuntu 19.10.

南风起 2024-07-22 08:09:46

此外,当验证您的代码是否符合 MISRA(或其他)标准时,静态分析工具(例如 LDRA)将不允许您调用具有返回类型的函数而不让其返回值,除非您将返回值显式转换为 (void )

Also when verifying your code complies to MISRA (or other) standards, static-analysis tools such as LDRA will not allow you to call a function that has a return type without having it return a value unless you explicitly cast the returned value to (void)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文