打破严格的走样和生活来讲述它?

时间:2014-08-05 10:22:47

标签: c++ c++11 strict-aliasing type-punning

我正在尝试在我在C ++ 11中编写的同一个应用程序中使用两个库LIBSVMLIBLINEAR。 LIBSVM和LIBLINEAR都在基本上是基于行的稀疏矩阵表示中输入它们:有节点结构

struct svm_node
{
    int index;
    double value;
};

,稀疏矩阵本身只是struct svm_node **,其中每一行都是struct svm_node *,行由index = -1终止。此结构的LIBLINEAR版本称为feature_node,具有相同的定义。虽然LIBSVM和LIBLINEAR是由同一作者撰写的,svm.hlinear.h,因此struct svm_nodestruct feature_node没有任何关联。

在某些情况下,我想创建一个内核SVM模型(仅由LIBSVM实现)和一个逻辑回归模型(仅由LIBLINEAR实现)我的数据。数据集传递给它们各自的库---在二进制级别上,相同的---稀疏矩阵表示,可能非常大,我宁愿避免memcpy()这一切。一个简单的reinterpret_cast<feature_node **>(svm_node_ptr_ptr_variable)似乎做得很好。

我也在发布版本中使用LLVM的完整程序优化(-flto),因此我希望确保代码不会以不可预测的方式进行优化。

有没有什么方法可以将{-1}}改为svm_node **,以避免可能由(当前或未来)编译器优化引起的任何破坏? feature_node **是否有帮助,如果有,我应该如何使用它?


如果__attribute__((__may_alias__))仅对类型有意义,那么如果我创建了自己的结构和指向结构的指针,它是否有用

__attribute__((__may_alias__))

然后将struct __attribute__((__may_alias__)) SparseElement { int index; double value; }; typedef SparseRow SparseElement * __attribute__((__may_alias__)); ed retinterpret_cast传递给LIBSVM和LIBLINEAR?

1 个答案:

答案 0 :(得分:3)

  

此结构的LIBLINEAR版本称为feature_node,具有相同的定义。

如果你使用工会,你会变得很好。 C ++特别允许(第9.2节)访问&#34;一个共同的初始子序列&#34;。

  

如果标准布局联合包含两个或多个共享公共初始序列的标准布局结构,并且标准布局联合对象当前包含这些标准布局结构中的一个,则允许检查公共初始他们中的任何一个。如果相应的成员具有布局兼容类型且两个成员都不是位字段,则两个标准布局结构共享一个共同的初始序列   两个都是具有相同宽度的位字段,用于一个或多个初始成员的序列。

即使指针上的reinterpret_cast也可以正常工作,因为经过左值到右值转换的类型是存在于内存中的对象的确切类型。