0

为什么编译器不为返回类型为类名的函数返回此指针而引发错误&

例如:在 readonly 、 readwrite 等函数中,即使我们注释 return *this 并且不返回任何内容,这似乎工作正常,并且链接机制在 main 函数中也完美工作。

这些函数会自动返回 *this 吗?

class OpenFile {
public:
  OpenFile(const std::string& filename);

  OpenFile& readonly();  // changes readonly_ to true
  OpenFile& readwrite(); // changes readonly_ to false
  OpenFile& createIfNotExist();
  OpenFile& blockSize(unsigned nbytes);

private:
  friend class File;
  std::string filename_;
  bool readonly_;          // defaults to false [for example]
  bool createIfNotExist_;  // defaults to false [for example]

  unsigned blockSize_;     // defaults to 4096 [for example]

};
inline OpenFile::OpenFile(const std::string& filename)
  : filename_         (filename)
  , readonly_         (false)
  , createIfNotExist_ (false)
  , blockSize_        (4096u)
{ }
inline OpenFile& OpenFile::readonly()
{ readonly_ = true; return *this; }
inline OpenFile& OpenFile::readwrite()
{ readonly_ = false; return *this; }
inline OpenFile& OpenFile::createIfNotExist()
{ createIfNotExist_ = true; return *this; }
inline OpenFile& OpenFile::blockSize(unsigned nbytes)
{ blockSize_ = nbytes; return *this; }

main()
{
//OpenFile *obj = new OpenFile();
  OpenFile f = OpenFile("foo.txt")
       .readonly()
       .createIfNotExist()
       .blockSize(1024);
}

删除return语句根本不会影响代码,像这样

inline OpenFile& OpenFile::readonly()
{ readonly_ = true;  }
inline OpenFile& OpenFile::readwrite()
{ readonly_ = false;  }
inline OpenFile& OpenFile::createIfNotExist()
{ createIfNotExist_ = true; }
inline OpenFile& OpenFile::blockSize(unsigned nbytes)
{ blockSize_ = nbytes;  }

编译器如何处理这些函数,还是通过查看返回类型自动返回 *this?

4

1 回答 1

4

How is the compiler treating these functions

in an undefined way

or is it automatically returning *this by looking at the return type?

no. the program's behaviour is not predictable and certainly won't be correct.

but it seems to work

in an unoptimised build, very likely. The register holding the this pointer is probably not being modified.

Wait until the optimiser starts inlining your code in your release build. Enjoy the fireworks.

Why doesn't the compiler complain?

If you enable warnings, it will. You should always enable all warnings. They help you to avoid incorrect code:

/tmp/gcc-explorer-compiler116311-75-17mquww/example.cpp: In member function 'OpenFile& OpenFile::readonly()':
28 : warning: no return statement in function returning non-void [-Wreturn-type]
{ readonly_ = true; }
^
Compiled ok

From §6.6.3 (2):

Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

于 2016-04-11T11:15:19.623 回答