转换为指向数组的指针 - c与c ++(或gcc与g ++)

时间:2017-04-07 14:48:11

标签: c++ arrays gcc

以下代码在编译为c代码(带文件后缀'.c'的gcc)时编译(并按预期工作)但在编译为c ++代码时抛出错误(带有文件后缀'.cpp'的gcc的g ++):

int sum_square_matrix(int *matrix, int size) {
    int (*m)[size] = (int(*)[])matrix;
    ...
}

使用g ++(或带有后缀.cpp的gcc)编译时会引发以下错误:

c_vs_cpp.c:4:32: error: cannot convert ‘int (*)[]’ to ‘int (*)[(((sizetype)(((ssizetype)size) + -1)) + 1)]’ in initialization
     int (*m)[size] = (int(*)[])matrix;

这种代码背后的动机是在预先不知道尺寸时将方矩阵处理为双维数组。

所以我的问题是:

  1. c ++标准中是否有任何与c标准不同的内容使得该播放非法?
  2. 用于实现相同目标的任何其他建议方法(除了使用丑陋的算术和服务函数手动访问矩阵中的元素)。最好是c / c ++中支持的常用方法。

1 个答案:

答案 0 :(得分:2)

  
      
  1. c ++标准中是否有任何与c标准不同的内容使得该播放非法?
  2.   

是。 C ++标准不允许可变长度数组†。 C标准(自C99起)。

  
      
  1. 用于实现相同目标的任何其他建议方法(除了使用丑陋的算术和服务函数手动访问矩阵中的元素)。
  2.   

将丑陋的算术包裹在助手类型中是非常微不足道的。一个简单的例子:

template<class T>
struct matrix_view
{
    T* matrix;
    size_t size;

    T* operator[](size_t i) {
        return matrix + i * size;
    }
};

template<class T>
auto
make_matrix_view(T* matrix, size_t size)
{
    return matrix_view<T>{matrix, size};
}

int sum_square_matrix(int *matrix, int size) {
    auto m = make_matrix_view(matrix, size);
    // ...
}

使用更多样板文件,你可以使matrix_view在标准算法和基于范围的循环中也可用(只有外循环;内循环不是那么简单)。

  

最好是c / c ++中支持的常用方法。

也许你可以设计一个宏,它使用c ++中显示的matrix_view和C中支持的任何强制转换方法。

†GCC确实支持VLA作为语言扩展,这就是为什么您的错误消息不能将其作为错误原因。无论出于何种原因,C ++实现都不同意您的转换。如果你说出演员阵容的大小,显然会这样做:

int (*m)[size] = (int(*)[size])matrix;

我认为这与C ++标准无关,只是C ++ VLA扩展的标准C和GCC实现之间存在差异。