2017-06-04 6 views
2

malloc()によって返されたポインタを多次元配列の名前として使いたいので、ポインタをキャストします。コンパイルすると、私はエラーを得た:なぜ同じタイプのレポートが互換性がないのですか?

clang++ -o cast cast.cpp 
cast.cpp:29:12: error: assigning to 'int8_t (*)[width]' from incompatible type 
     'int8_t (*)[width]' 
    int8line = (int8_t (*)[width])(array); 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
1 error generated. 

しかし、Linux上で同じプラットフォーム(OS用X)上のicpcg++/icpcでコンパイル、エラーがスローされません。

更新:幅が可変であるため、constにできません。


テストしたコンパイラは、次のとおり

Mac OS X

icpc (ICC) 17.0.4 20170411 

clang --version 
Apple LLVM version 8.1.0 (clang-802.0.42) 
Target: x86_64-apple-darwin16.6.0 
Thread model: posix 

Linux 2.6.32:

icpc (ICC) 14.0.0 20130728 
g++ (GCC) 4.4.6 20110731 

結果がなければならない:

icpc -std=c++11 -o cast cast.cpp && ./cast 5 
0 1 2 3 4 
5 6 7 8 9 

0 1 2 3 4 
5 6 7 8 9 

最小コンパイル可能コード(更新):

#include <iostream> 
#include <cstdint> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    if (argc != 2) 
    { 
    cerr << "needs one argument\n"; 
    exit(EXIT_FAILURE); 
    } 
    long width = atol(argv[1]); 

    int8_t *array = static_cast<int8_t(*)>(malloc(sizeof(int8_t)*2*width)); 
    for (int i = 0; i < 2*width; i++) 
    array[i] = i; 

    for (int j = 0; j < 2; j++) 
    { 
    for (int i = 0; i < width; i++) 
    { 
     cout << static_cast<int>(array[i+j*width]); 
     if (i < (width-1)) 
     cout << '\t'; 
    } 
    cout << '\n'; 
    } 

    cout << '\n'; 

    int8_t (*int8line)[width]; 
    int8line = (int8_t (*)[width])(array); 
    for (int j = 0; j < 2; j++) 
    { 
    for (int i = 0; i < width; i++) 
    { 
     cout << static_cast<int>(int8line[j][i]); 
     if (i < (width-1)) 
     cout << '\t'; 
    } 
    cout << '\n'; 
    } 

    free(array); 
    exit(EXIT_SUCCESS); 
} 
+1

'long width = 5;' widthはconstにする必要があります – Loreto

+3

C++で 'malloc'を使用するのは非常に奇妙で、C言語では* cast *と同じくらい奇妙です。これはあなたの質問が[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)であり、X部分(問題の最も重要な部分)に対する答えは、 'new int8_t [width]'または 'std :: vector 'を使用します。 – Sebivor

+0

[This(http://coliru.stacked-crooked.com/a/fd11dba2af9b5213)はGCCではコンパイルされますが、clangではコンパイルされません。それは、clangが可変長配列へのポインタを受け付けない理由です。 –

答えて

1

私はそれが普通の定数ではないことを確信しています。他のコンパイラはこの変数の不変性を認識するかもしれませんが、そのような推測は標準で指定されたものではありません。あなたは、変数widthを一定にした場合

、それが動作するはずです:

const long width = 5; 
+0

おそらく、 'long width = atol(argv [1])'を説明すると結果は変わらないでしょうか? – Eli4ph

+0

@ Eli4ph:変数は依然として実質的に一定のままであるため。これは拡張子としてコンパイラのいくつかによって検出されますが、標準仕様では一般的には必要ありません。 –

0

を非constexprのwidthを持つvaraible length arrayと呼ばれ、標準C++ではありません。

したがって、int8lineのタイプは奇妙な状態です。int8_t (*)[width]は実際のタイプではないため、コンパイラは混乱したエラーメッセージを生成します。

Zbynek Vyskovsky - kvr000 pointed outを使用すると、widthがコンパイル時に既知の定数式になるため、const long width = 5を使用するとこれが機能します。これにより、配列は可変長配列になりません。

おそらくstd::vectorを使用してください。

関連する問題