是否可以声明一个C ++函数,使得返回值不能被忽略? [英] Can a C++ function be declared such that the return value cannot be ignored?

查看:208
本文介绍了是否可以声明一个C ++函数,使得返回值不能被忽略?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图确定是否可以声明一个C ++函数,返回值不能被忽略(理想情况下在编译时检测)。我试图声明一个类与私人(或在C + + 11,删除 d) operator void()尝试在未使用返回值时捕获隐式转换为void。



这里是一个示例程序: / p>

  class Unignorable {
operator void();
};

Unignorable foo()
{
return Unignorable();
}

int main()
{
foo();
return 0;不幸的是,我的编译器(clang-703.0.31)说:

>

  test.cpp:2:5:warning:将Unignorable转换为void的转换函数永远不会使用
运算符void();
^

,并且在调用<$ c时不会引发任何错误或警告$ c> foo()。所以,这不会工作。有没有其他方法来做到这一点?

解决方案

对于C ++ 11或C ++ 14或更高版本的解答可能会很好。基本上你有3个选择:


  1. 获取C ++ 17能够使用 [[nodiscard] ]

  2. 在g ++(也是clang ++)中,使用编译器扩展,例如 __ wur c>

  3. 使用运行时检查在单元测试期间捕获问题

  4. __ attribute__((__warn_unused_result _






如果这3个都不可能,那么还有一种方法,负面编译。定义 Unignorable 如下:

  struct Unignorable {
Unignorable()= default;
#ifdef NEGATIVE_COMPILE
Unignorable(const Unignorable&)= delete; // C ++ 11
Unignorable& operator =(const Unignorable&)= delete;
// private:Unignorable(const Unignorable&); public:// C ++ 03
// private:Unignorable& operator =(const Unignorable&); public:// C ++ 03
/ *类似的东西for move-constructor if needed * /
#endif
};

现在使用 -DNEGATIVE_COMPILE 其他编译器如MSVC。 :
$ b

  auto x = foo(); //错误

但是,忽略结果 em>:

  foo(); //没有错误

使用任何现代代码浏览器(如eclipse-cdt)出现 foo()并修复那些没有给出错误的地方。在新编译中,只需删除NEGATIVE_COMPILE的预定义宏。



这比找到 foo()并检查其返回值可能会好一些,很多函数像 foo(),你可能不想忽略返回值。



但将适用于所有版本的C ++与所有的编译器。


I'm trying to determine whether a C++ function can be declared in such a way that the return value cannot be ignored (ideally detected at compile time). I tried to declare a class with a private (or in C++11, deleted) operator void() to try to catch the implicit conversion to void when a return value is unused.

Here's an example program:

class Unignorable {
    operator void();
};

Unignorable foo()
{
    return Unignorable();
}

int main()
{
    foo();
    return 0;
}

Unfortunately, my compiler (clang-703.0.31) says:

test.cpp:2:5: warning: conversion function converting 'Unignorable' to 'void' will never be used
    operator void();
    ^

and doesn't raise any error or warning on the call to foo(). So, that won't work. Is there any other way to do this? Answers specific to C++11 or C++14 or later would be fine.

解决方案

To summarize from other answers & comments, basically you have 3 choices:

  1. Get C++17 to be able to use [[nodiscard]]
  2. In g++ (also clang++), use compiler extensions like __wur (defined as __attribute__ ((__warn_unused_result__)))
  3. Use runtime checks to catch the problem during unit testing


If all of these 3 are not possible, then there is one more way, which is kind of "Negative compiling". Define your Unignorable as below:

struct Unignorable {
  Unignorable () = default;
#ifdef NEGATIVE_COMPILE
  Unignorable (const Unignorable&) = delete;  // C++11
  Unignorable& operator= (const Unignorable&) = delete;
  //private: Unignorable (const Unignorable&); public:  // C++03
  //private: Unignorable& operator= (const Unignorable&); public: // C++03
  /* similar thing for move-constructor if needed */
#endif
};

Now compile with -DNEGATIVE_COMPILE or equivalent in other compilers like MSVC. It will give errors at wherever the result is Not ignored:

auto x = foo();  // error

However, it will not give any error wherever the result is ignored:

foo(); // no error

Using any modern code browser (like eclipse-cdt), you may find all the occurrences of foo() and fix those places which didn't give error. In the new compilation, simply remove the pre-defined macro for "NEGATIVE_COMPILE".

This might be bit better compared to simply finding foo() and checking for its return, because there might be many functions like foo() where you may not want to ignore the return value.

This is bit tedious, but will work for all the versions of C++ with all the compilers.

这篇关于是否可以声明一个C ++函数,使得返回值不能被忽略?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆