Monday, March 28, 2022

[SOLVED] Conversions to arrays of unknown bound: g++ vs. clang++

Issue

Note: this is the follow-up question for this question.

Sample code (t334.cpp):

typedef int T0;
typedef T0  T1[];
typedef T1* T2[];

T1 x1 = { 13 };
T2 x2 = { &x1 };

Invocations:

$ g++ t334.cpp -std=c++11 -pedantic -Wall -Wextra -c
t334.cpp:6:11: warning: conversions to arrays of unknown bound are only available with ‘-std=c++20’ or ‘-std=gnu++20’ [-Wpedantic]
    6 | T2 x2 = { &x1 };
      |           ^~~

$ clang++ t334.cpp -std=c++11 -pedantic -Wall -Wextra -c
t334.cpp:6:11: error: cannot initialize an array element of type 'T1 *' (aka 'T0 (*)[]') with an rvalue of type 'T0 (*)[1]'
T2 x2 = { &x1 };
          ^~~

Can someone explain, what is wrong with this C++ code?

Note: the equivalent C code is valid, because int (*)[] and int (*)[1] are compatible. Meaning that in C++ they aren't?


Solution

The first definition is of an array of known bound that is deduced from the initializer. It has the same effect as:

int x1[1] = {13};

That means x1 has type int[1], and &x1 has type int (*)[1].

The second definition is trying to initialize a variable of type int (*)[] from a (brace-enclosed) expression of type int (*)[1]. In other words, it requires a conversion from a pointer to array with known bound to a pointer to array with unknown bound.

Just like GCC tells you, this type of conversion only became allowed starting in C++20. If you compile your code with a recent version of Clang with -std=c++20, it should compile. See https://godbolt.org/z/4zb5xx658



Answered By - Brian Bi
Answer Checked By - Clifford M. (WPSolving Volunteer)