struct svm_node { int index; double value; };
稀疏矩阵本身只是struct svm_node **,其中每一行都是struct svm_node *,行以index = -1结尾.此结构的LIBLINEAR版本称为feature_node,具有相同的定义.尽管LIBSVM和LIBLINEAR是由相同的作者编写的,但svm.h和linear.h以及struct svm_node和struct feature_node没有任何关系.
在某些情况下,我想创建一个内核SVM模型(仅由LIBSVM实现)和一个逻辑回归模型(仅由LIBLINEAR实现)我的数据.数据集传递给它们各自的库—在二进制级别上,相同的—稀疏矩阵表示,可能非常大,我宁愿避免memcpy()这一切.一个简单的reinterpret_cast< feature_node **>(svm_node_ptr_ptr_variable)似乎做得很好.
我还在发布版本中使用LLVM的完整程序优化(-flto),因此我希望确保代码不会以不可预测的方式进行优化.
有没有什么方法可以将type-pun svm_node **转换为feature_node **,以避免可能由(当前或未来)编译器优化引起的任何破坏? __attribute __((__ may_alias__))在这里有帮助,如果有,我应该如何使用它?
如果__attribute __((__ may_alias__))仅对类型有意义,那么如果我创建了自己的struct和指向struct的结构,它是否有效
struct __attribute__((__may_alias__)) SparseElement { int index; double value; }; typedef SparseRow SparseElement * __attribute__((__may_alias__));
然后将retinterpret_casted SparseRow *传递给LIBSVM和LIBLINEAR?
解决方法
The LIBLINEAR version of this struct is called feature_node and has identical definition.
如果你使用工会,你就是金. C特别允许(第9.2节)访问“共同的初始子序列”.
If a standard-layout union contains two or more standard-layout structs that share a common initial sequence,and if the standard-layout union object currently contains one of these standard-layout structs,it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or
both are bit-fields with the same width for a sequence of one or more initial members.
即使是指针上的reinterpret_cast也应该可以正常工作,因为经过左值到右值转换的类型是存储在那里的对象的确切类型.