将前向声明的类型转换为 void 是否合法?
Is it legal to cast a forward-declared type to void?
下面是一个C++头文件,在g++和clang下编译没有错误,但是在MSVC2015下,在(void) copyFrom
行出错,错误为C2027: use of undefined type 'blah::SomeOtherClass'
.
我的问题是:根据 C++ 标准,这段代码是否合法?或者,如果代码不正确(即因为将参数强制转换为 (void) 合法地需要的不仅仅是前向声明),那么在不引入 copyFrom
参数的情况下保留我的 DOxygen 文档的好方法是什么不需要的 parameter copyFrom was never referenced
警告进入我的编译器输出? (请注意,SomeOtherClass
的完整定义此时不可用,因为 SomeOtherClass
取决于 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
更新:根据 Francois 的要求,这里是我的程序在使用 MSVC 19.0.24210.0
构建时使用的构建(不是关于 C++ 标准要求的问题的答案应该取决于特定的行为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 ...]
完整故事请参考回答。
根据 cppref,对于 (type-name) expression
(强调我的)
If type-name
is void
, then expression
is evaluated for its side-effects and its returned value is discarded, same as when expression
is used on its own, as an expression statement.
也就是说,(void)copyFrom
等同于 copyFrom
,后者没有任何作用,并且在 C++ 中不应要求完整类型。
顺便说一下,您的代码可以在 MSVC 2017 中正常编译 (live)。
要抑制编译警告,您可以考虑:
std::addressof(copyFrom)
下面是一个C++头文件,在g++和clang下编译没有错误,但是在MSVC2015下,在(void) copyFrom
行出错,错误为C2027: use of undefined type 'blah::SomeOtherClass'
.
我的问题是:根据 C++ 标准,这段代码是否合法?或者,如果代码不正确(即因为将参数强制转换为 (void) 合法地需要的不仅仅是前向声明),那么在不引入 copyFrom
参数的情况下保留我的 DOxygen 文档的好方法是什么不需要的 parameter copyFrom was never referenced
警告进入我的编译器输出? (请注意,SomeOtherClass
的完整定义此时不可用,因为 SomeOtherClass
取决于 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
更新:根据 Francois 的要求,这里是我的程序在使用 MSVC 19.0.24210.0
构建时使用的构建(不是关于 C++ 标准要求的问题的答案应该取决于特定的行为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 ...]
完整故事请参考
根据 cppref,对于 (type-name) expression
(强调我的)
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.
也就是说,(void)copyFrom
等同于 copyFrom
,后者没有任何作用,并且在 C++ 中不应要求完整类型。
顺便说一下,您的代码可以在 MSVC 2017 中正常编译 (live)。
要抑制编译警告,您可以考虑:
std::addressof(copyFrom)