Below is a C++ header file that compiles without error under g++ and clang, but under MSVC2015, it errors out on the (void) copyFrom
line, with the error C2027: use of undefined type 'blah::SomeOtherClass'
.
My question is: is this code legal according to the C++ standard? Or if the code is not correct (i.e. because casting a parameter to (void) legitimately requires more than just a forward-declaration), then what would be a good way to retain my DOxygen documentation for the copyFrom
argument without introducing unwanted parameter copyFrom was never referenced
warnings into my compiler-output? (Note that the full definition of SomeOtherClass
isn't available at this point, since SomeOtherClass
depends on DummyImplementation
)
#ifndef blah_h
#define blah_h
namespace blah {
class SomeOtherClass;
/** Example of the problem at hand */
class DummyImplementation
{
public:
/** Dummy implemention of CopyFrom().
* @param copyFrom This parameter is ignored.
* @returns zero.
*/
int CopyFrom(const SomeOtherClass & copyFrom)
{
(void) copyFrom; // error C2027: use of undefined type 'blah::SomeOtherClass'
return 0;
}
};
} // end namespace blah
#endif
Update: Per Francois' request, here are the build my program uses when building with MSVC 19.0.24210.0
(not that the answer to a question about the requirements of the C++ standard should depend on the behavior of a particular version of MSVC):
cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline /nologo /MP
/arch:SSE2 /Zi -O2 -MD -Zc:strictStrings -GR -W3 -w34100 -w34189 -w44996
-EHsc -D_WIN32_WINNT=0x0601 -DNDEBUG -D__WIN32__ -D_USE_MATH_DEFINES
-DQT_NO_CAST_ASCII -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
[... various -I flags omitted ...]
For the full story, please refer to this answer.
According to cppref, for (type-name) expression
(emphasis mine)
If
type-name
isvoid
, thenexpression
is evaluated for its side-effects and its returned value is discarded, same as whenexpression
is used on its own, as an expression statement.
That is, (void)copyFrom
is equivalent to copyFrom
which has no effect, and should not require a complete type in C++.
By the way, your code compiles fine with MSVC 2017 (live).
To suppress the compiler warning, you may consider:
std::addressof(copyFrom)