GCC 内联程序集错误:无法获取"this"的地址,这是一个右值表达式
GCC inline assembly error: Cannot take the address of 'this', which is an rvalue expression
我仍在与GCC作斗争-编译以下内联汇编代码(使用-fasm块,它启用Intel风格汇编语法)会给我带来一个奇怪的错误无法获取'this'的地址,这是一个右值表达式。。。
MyClass::MyFunction()
{
_asm
{
//...
mov ebx, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
mov eax, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
};
}
为什么我可以在寄存器中存储指向不同对象的指针,但不能使用指向MyClass实例的指针?
这是因为出于优化目的,编译器可能会自行决定将this
存储在寄存器(通常为ECX
)中,而不是存储单元中,或者因为调用约定明确指定它应该这样做。
在这种情况下,您不能获取它的地址,因为寄存器不是可寻址的内存。
您可以使用这样的东西:
#include <stdio.h>
class A{
public:
void* work(){
void* result;
asm( "mov %%eax, %%eax"
: "=a" (result) /* put contents of EAX to result*/
: "a"(this) /* put this to EAX */
);
return result;
}
};
int main(){
A a;
printf("%x - %xn", &a, a.work());
}
请在此处查看传递到内联asm的操作数的更多详细信息
实际上,每个实现都定义了自己的规则关于asm。在g++的情况下,当您编写mov
ebx, something
时,g++需要something
的地址才能生成指令。(顺便说一句,真的不足为奇装配工工作。)this
没有地址。(这就是右值的意思。)该实现可以将this
视为一个特殊的内联汇编程序中的case,并将其替换为代码中的那个位置。g++不这么做,可能是因为它另一个更通用的机制(eldergeorge的解决方案)来处理这个问题。
相关文章:
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 编写了一个C++代码来检查表达式是否具有平衡括号并且我的代码未运行.我已经卡了一天了
- void() 是一个有效的C++表达式吗?
- 如何在一个表达式中生成并返回结果?
- 编译器错误:函数调用在常量表达式中必须有一个常量值
- 如何将正则表达式向量与一个字符串匹配?
- 为什么一个表达式中的 std::string 连接给出的结果与逐个字符不同的结果?
- 一次包含一个 #include 表达式的多个头文件?
- 在另一个成员函数中调用成员函数时'int'之前的预期主表达式
- 使用折叠表达式构造一个平凡的对象
- 是否有一个上下文表达式`a.b :: c`有意义
- 使用参数包和元组创建一个简单的表达式类
- 可以将算术表达式作为参数传递给一个函数来描述其中的逻辑
- CUDA C++:文件中 kernel.cu 应有一个表达式
- 如果我将 decltype 应用于产生右值的表达式,我是否总是得到一个指针?C++
- 将一个特定字符替换为正则表达式匹配中的另一个字符
- 如何为字符串编写正则表达式,其中包含一个数字至少一个数字,并且不包含任何字母
- constexpr 表达式和变量生存期,G++ 和 Clang 不同意的一个例子