可选的Int参数在CPP目标上导致的编译错误

来源:互联网 发布:linux 切换root 编辑:程序博客网 时间:2024/06/07 22:32

这是昨天开发中遇到的另外一个平台相关小问题。见代码如下:

typedef Request = { var code: Int; var data: String; }

public function request(?requestCode: Int = 1, ?requestData: String) {

  var requestList: Array<Request> = [];

  requestList.push({ code: requestCode, data: requestData });

  ...

}

这段代码在Flash目标上可正确构建,但在CPP目标上(准确的说是Windows目标)却出错,而且不是haXe构建出错,而是haXe生成的CPP代码的编译错误,错误信息是无法把Dynamic转换为&Int,找到release目录中haXe生成的CPP代码中的对应位置,发现是上面的代码中requestList.push那行中,code: requestCode赋值的问题,但是那里并没有Dynamic啊,requestCode应该是Int型啊?真是奇怪。

深入的想了想,终于理解了这个问题。这里就要谈到haXe的一个很有趣也很实用的语言特性了,那就是haXe的基本数值类型Int, Float是允许为空的,这个特性有时很实用,比如你可以用null来表示一种特殊情况,尤其是上面的代码中作为函数的默认参数时,这样是很方便的,这里haXe的Int更像是java中的Integer对象。

那面上面的代码构建错误说明了什么呢?

我的分析是:

1. 函数的可选参数,以及可为空的基本类型比如Null<Int>, Null<Float>,实际上是作为Dynamic类型的。即使上面的代码中指定了默认值为1也并不影响编译器对类型的选择

2. 从生成的c++目标代码中来看,对于声明为Int的变量,在c++中则是直接用基本类型Int的,从而保证很高的性能

3. 这样一来,上面出错的那一行,试图把Null<Int>赋值给Int,就导致了CPP编译出错

既然找到了问题,那么在我的代码中修正就很简单了,不必多说。

这严格说是haXe编译器的hxcpp后端问题,从合法的haXe代码生成出了不合法的c++代码,这确实是bug。希望以后haXe对这类问题至少要有编译期警告,否则平台的不一致行为导致此类问题难于定位。

又是一个平台差异性问题,这里仅做记载。