我写这样一段代码,其含义非常清晰易懂:
void func(int i)
{
uint64 pos;
if(i > 32)
pos = Pos1;
else
pos = Pos2;
goto pos;
Pos1:
func1(); return;
Pos2:
func2(); return;
}
十分遗憾目前C++是不允许这样做的。老旧的C语言时期就不允许这种做法。然而一个标签事实上正是一个地址而已。在32位状态下,标签是一个明确的32位地址值。64位状态下就是64位的。至少,一个标签将始终同一个指针具有一样的大小。其本质就是一个值而已。汇编语言是允许对任意的一个同地址位数一样的值进行跳转的。因此在技术上上面的事情毫无难度。
在正式的编程中,goto是不可避免的。很多情形下goto是唯一高效清晰的方法。定义一个标签,然后跳转,非常自然。然而不仅如此,我们在有的时候甚至需要一个标签变量,来配合goto实现更为紧凑的表达。可惜语言自身不允许。
在VC的win32(32位)模式下,可以内联汇编。就是__asm关键字。借助内联汇编,可以实现将一个标签赋值给一个变量。大致方法如下:
#define set_jump_position(x, pos) ___asm{ mov x, pos; }
而跳转方法也需要通过宏。
#define jump_to_position(pos) ___asm{ jmp pos; }
于是最上面的那段可以写成下面的形式:
void func(int i)
{
uint32 pos;
if(i > 32)
set_jump_position(pos, Pos1);
else
set_jump_position(pos, Pos2);
jump_to_position(pos);
Pos1:
func1(); return;
Pos2:
func2(); return;
}
然而非常可惜,x64模式下VC的内联汇编是根本不能使用的。除非使用别的平台。
这实在应该归结为语言特性不足。将一个标签赋值给一个同指针等长的变量真的那么不可理喻吗?
我不认为编译器的优化能够在这么大跨度的范围内也能达到人能达到的理想状态。即使能,代码本身不理想这一条足够摧残大脑的意识。对此我只能选择无语。凡是有这种需求的大函数,要么改用低效的结构方式,要么,估计就只能用真汇编去封装dll了。这两种方法都是非常不理想的。
除了C++,再没有别的什么语言对我个人而言是理想的。然而现在我发现的一些问题,除了修改语言本身之外,确实别无它法。未来的编程语言应该允许程序员 按 照 自 己 喜 欢 的 方 式 定 义 语 法。而底层仅仅只是对目标硬件实现的汇编最优化。