C++开发遇'&' requires l-value报错 /permissive选项失效排查
错误原因
C++标准明确规定,取地址运算符&只能作用于左值(即拥有持久内存地址、有明确标识符的对象),你代码中所有取地址操作的操作数全是函数按值返回的临时对象(属于右值),本身没有固定内存地址,在严格标准编译模式下会直接触发该错误。
之前开启/permissive时MSVC会启用非标准扩展,隐式给这类临时对象分配短暂栈空间放行取地址操作,当该选项失效(比如切到标准一致性模式/permissive-、编译器版本升级移除相关宽松逻辑)后,这类非标准写法就会直接编译失败。
你代码里具体触发错误的点有3处:
CAM::GET_CAM_COORD(cam)返回值是按值传递的Vector3临时对象,直接对其取地址非法rot_to_direction(&rot)的返回值是按值传递的Vector3临时对象,直接作为multiply的参数传参时本身就是临时值multiply(...)的返回值同样是按值传递的Vector3临时对象,直接对其取地址非法
修复方案
推荐方案:调整函数参数类型(最合理)
Vector3是只有3个成员的小结构体,完全没必要传指针,改用const引用传参既符合C++写法规范,也从根源上避免了取地址的问题,修改后的函数实现如下:
Vector3 add(const Vector3& vectorA, const Vector3& vectorB) { Vector3 result; result.x = vectorA.x + vectorB.x; result.y = vectorA.y + vectorB.y; result.z = vectorA.z + vectorB.z; return result; } Vector3 multiply(const Vector3& vector, float scalar) { Vector3 result; result.x = vector.x * scalar; result.y = vector.y * scalar; result.z = vector.z * scalar; return result; } Vector3 rot_to_direction(const Vector3& rot) { constexpr float degToRad = 0.0174532924f; float radiansZ = rot.z * degToRad; float radiansX = rot.x * degToRad; float cosX = abs(cos(radiansX)); Vector3 dir; dir.x = -sin(radiansZ) * cosX; dir.y = cos(radiansZ) * cosX; dir.z = sin(radiansX); return dir; }
对应调用代码去掉所有不必要的取地址符即可:
auto c = add(CAM::GET_CAM_COORD(cam), multiply(rot_to_direction(rot), speed));
兼容方案:不修改原函数签名
如果这几个工具函数是第三方依赖提供的、你没有修改权限,就需要先把所有临时返回值存储为有名字的局部变量(局部变量是合法左值),再取地址传参:
// 先将临时值落地为局部变量 Vector3 camPos = CAM::GET_CAM_COORD(cam); Vector3 dir = rot_to_direction(&rot); Vector3 offset = multiply(&dir, speed); // 局部变量为左值,可合法取地址 auto c = add(&camPos, &offset);
提示:不要依赖
/permissive开启的非标准扩展写代码,这类写法在GCC、Clang等其他编译器下会直接报错,也会在后续MSVC版本升级中出现兼容问题。
内容的提问来源于stack exchange,提问作者Skeyoter
相关产品推荐
相关产品推荐

