我正在编写一些调试宏,其中一个宏是在没有将返回值赋给变量时捕获函数的返回值。在返回值在调试中很有用但在发布版本中不需要的情况下,这可能很有用。
以下宏适用于整数和指针类型:
#define DebugReturn(TYPE,fcn) \
int fcn##_return; \
__asm("movl %%eax,%0":"=mr"(fcn##_return)); \
TYPE fcn##_returned = (TYPE) fcn##_return
例如:
static int Foobar( int &x, int &y )
{
x = 7;
y = 8;
return 9;
}
Foobar( x, y );
DebugReturn( int, Foobar );
DebugTraceFunction( "Foobar( x, y );", x, y, Foobar_returned );
将正确显示9的返回值。
我已尝试使用浮点类型的以下宏的变体,但它们都不起作用:
#define DebugReturnFloatingPoint(fcn) \
double register fcn##_return; \
float fcn##_returned = 2.718281828; \
__asm("fstl %0":"=m"(fcn##_returned):"t"(fcn##_return))
例如:
static float FOOBAR( int x, int y )
{
return 3.14159;
}
FOOBAR( x, y );
DebugReturnFloatingPoint( FOOBAR );
DebugTraceFunction( "FOOBAR( x, y );", x, y, FOOBAR_returned );
无论FOOBAR实际返回什么值,始终显示返回值3.0056636E + 33。如果我删除行双寄存器fcn ## _ return;和输入参数:" t"(fcn ## _ return),它总是显示返回值为零。初始值为2.718281828的原因是检查该值是否已由汇编指令实际修改。我并不关心结果的准确性。
当然,我可以很容易地编写浮点FOOBAR_returned = FOOBAR(x,y),但是使用宏的原因是为了便于清理最终版本中的代码。宏将被定义为发布版本中的空字符串,但在最终版本中我想完全删除它们而没有任何未引用的局部变量。
那我的浮点指令出了什么问题?