一个VS2010错误?允许将非常量引用绑定到右值,甚至没有警告
One VS2010 bug ? Allowing binding non-const reference to rvalue WITHOUT EVEN a warning?
string foo() { return "hello"; }
int main()
{
//below should be illegal for binding a non-const (lvalue) reference to a rvalue
string& tem = foo();
//below should be the correct one as only const reference can be bind to rvalue(most important const)
const string& constTem = foo();
}
- GCC 是给出编译错误的好方法:从
std::string
类型的临时初始化无效的std::string&
类型的非 const 引用 - VS2008还不错,因为它至少给出了一个编译警告:警告 C4239:使用了非标准扩展:"正在初始化":从
std::string
到std::string &
A 非常量的转换引用只能绑定到左值 - 有问题的来了 - VS2010(SP1( 没有任何问题错误或警告,为什么??!!我知道VS2010中的右值引用可用于与右值绑定,但我没有使用
&&
,而是在演示代码中,我只是使用非常量左值引用!
somone可以帮我解释VS2010的行为吗?这是一个错误吗!?谢谢
这是VS编译器的已知问题/功能。他们一直允许这样做,并且似乎没有任何推动删除该扩展名。
编译器将在打开禁用语言扩展的情况下发出错误,并在/W4 处发出警告。但是,删除此代码将破坏以前编译的代码,Microsoft非常不愿意这样做。这也是他们不会修复他们的SFINAE支持的原因。
几年
和许多版本的Visual Studio之后,我们仍然有这个"扩展",引起惊喜和头痛。叹息。。。
解决方法是简单地将警告 C4239 变成错误。这将防止 MSVC 编译尝试将非常量左值引用绑定到临时引用的代码,并为您提供一个很好的清晰编译器错误。只需将/we4239
添加到编译器定义或cl
命令行参数即可。
在 Visual Studio 中:项目属性> C/C++> 所有选项>将特定警告视为错误>添加4239
,并确保用分号分隔任何其他数字。
在CMake中:
if(MSVC)
add_definitions("/we4239")
endif()
这似乎比使用 /Za
禁用所有语言扩展要好得多,官方不建议这样做。在我的大型代码库中,添加/Za
会导致 Microsoft 自己的 winnt.h
标头出现 1500 多个编译器错误。
这个问题有一个更令人讨厌的变体:
class Foo {
int _val;
public:
Foo(int v) : _val(v) {}
void F() { std::cout << _val << std::endl; }
};
class Bar {
Foo& f;
public:
Bar(Foo& f) : f(f) {}
void F() { f.F(); }
};
int main() {
Bar b(Foo(3));
b.F();
}
那么:在打电话给b.F()
时,b.f
指向什么? 上面的示例使用 VS2013 默认调试设置编译,运行时不会崩溃并打印3
,但我怀疑任何更复杂的示例都会导致堆栈损坏。 如果没有,并且编译器正在做一些"聪明"的事情来使其工作,那么我想它真正在做的是这样的:
class Foo {
int _val;
public:
Foo(int v) : _val(v) {}
void F() { std::cout << _val << std::endl; }
};
class Bar {
Foo f;
public:
Bar(Foo&& f) : f(f) {}
void F() { f.F(); }
};
int main() {
Bar b(Foo(3));
b.F();
}
相关文章:
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在使用GPU支持编译Tensorflow时,会遇到CUDA_TOOLKIT_PATH未绑定变量
- 视觉studo 2019中的漫画和静态/动态绑定
- 将自由函数绑定为类成员函数
- 将常量指针引用绑定到非常量指针
- 在派生类中绑定非静态模板化成员函数
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在 openGL 中多次绑定缓冲区
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 使用结构化绑定'Reflection'
- 为什么 std::绑定错误参数可以成功?
- 警告绑定到临时值的 clang 是否正确
- sc_start警告 W571 表示信号/端口绑定失败
- 理解警告:将r值绑定到l值引用
- 关于在构造函数中将临时绑定到引用成员的虚假警告
- 为什么 GCC 5.3.0 在将引用绑定到指针时发出警告"this"
- 一个VS2010错误?允许将非常量引用绑定到右值,甚至没有警告