Re: Is "T[N][]" (or "T[N][][M]") indirectly legal?
Am 20.09.2013 15:06, schrieb Daryle Walker:
On Wednesday, September 18, 2013 2:20:09 PM UTC-4, Daniel Kr?gler wrote:
No, I mean things like I said in the Subject line:
T[N][]
T[N][][][M]
The compiler (rightfully) prevents these when I use these lexical forms.
But can I create them indirectly via typedefs?
No, you cannot, because those are excluded from valid types, see my
previous quote referring to 8.3.4 [dcl.array] p1. This was already clear
in C++03, where we find a similar constraint in above mentioned paragraph:
"When several ?array of? specifications are adjacent, a multidimensional
array is created; the constant expressions that specify the bounds of
the arrays can be omitted only for the first member of the sequence."
(Make a type-alias to an array
with unspecified-bound, then use that as the element type for another array
type-alias.) I haven't tried this, but I'm extrapolating from the
"successful" trials with using 0 as an extent.
Please be more precise what you mean by that. In both C++03 and C++11 an
array dimension can only be a positive value or it can be omitted
(unbound) in a type declaration. A zero value is not valid (Some buggy
compilers still accept that though).
With multidimensional arrays, the zero-extent can be at any place.
If so, this compiler would be buggy. According to 8.3.4 [dcl.array] p1:
"[..] T is called the array element type; this type shall not be a [..],
an array of unknown or runtime bound, [..]."
Are you using a C++14 draft?
I quoted wording from a recent draft but that was already true in C++03
and in C++11. The wording was slightly different, because of a CWG issue
improving the state of another issue with arrays,
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#619
plus by other wording changes due to introduction of "arrays of runtime
bounds", but even in C++03 it was clear, which dimension could be
omitted and which not (see above quote). Note that CWG 619 nor the
introduction of arrays of runtime bounds have actually changed the state
of affairs in this discussion.
I'm looking at the C++11 Standard, and it bans
the following as array element types: reference types, (cv-) void, function
types, and abstract class types. It doesn't not mention incomplete types in
general at all nor are arrays of unknown-bound listed. If C++14 clarifies
this, I'll be content with that since I'm aiming my code for C++17.
No, this hasn't anything to do with C++14. In C++11, for example, the
relevant part in the standard is 8.3.4 [dcl.array] p3:
"When several ?array of? specifications are adjacent, a multidimensional
array is created; only the first of the constant expressions that
specify the bounds of the arrays may be omitted."
Paragraph 3 of that section, in C++11, says only the first extent can be of
unknown bound, but it also talks about several "array of" declarations being
adjacent. They won't be lexically adjacent if I use stupid typedef tricks,
so does the Standard just ban them just lexically or indirectly too?
Can you please provide a concrete example that would allow this? IMO the
meaning of "first" is unambiguous in this context.
This would be another compiler defect, because applying sizeof to an
incomplete type is ill-formed:
"The sizeof operator shall not be applied to an expression that has [..]
incomplete type, [..], to the parenthesized name of such types, [..]"
* Declaring an array type that has any extent as unbound besides the
first
flags an error on my GCC 4.7 setup. But I can indirectly create arrays
with an unbound non-first extent via typedefs in recursive variadic
class
templates. When I glanced at the Standard, it seemed to support banning
such array declarations directly, but indirect means didn't seem banned.
I do not understand what you mean by direct or indirect means in this
contact. The standard clearly says that such types are not allowed, it
doesn't distinguish direct or indirect ways to form them.
Are non-first unbound extents actually permitted or not? (If not, then
GCC 4.7 has a bug there, too.)
Again, please provide a concrete, short code example.
// From memory, not tested (I've changed stuff a lot.)
template < typename T, unsigned ...N > struct MyArray;
template < typename T > struct MyArray {
using value_type = T; // can these combined? or only with
"typedef"?
using data_type = T;
data_type data_;
};
template < typename T, unsigned N0, unsigned ...M >
struct MyArray<T, N0, M...> {
using value_type = T;
using element_type = typename MyArray<T, M...>::data_type;
using data_type = element_type[N0];
data_type data_;
};
// These are all approved, and their "sizeof"s are 0.
MyArray<0> e1, e2[6];
MyArray<3, 0> e3;
This code cannot be well-formed in any reasonable way, please provide a
fixed version. Here is my attempt to fix your code, but it does not lead
to arrays of invalid bounds.
template <typename T, unsigned ...N > struct MyArray;
template <typename T >
struct MyArray<T, 0>
{
using value_type = T;
using data_type = T;
data_type data_;
};
template <typename T, unsigned N0, unsigned ...M>
struct MyArray<T, N0, M...> {
using value_type = T;
using element_type = typename MyArray<T, M...>::data_type;
using data_type = element_type[N0];
data_type data_;
};
MyArray<int, 0> e1, e2[6];
MyArray<int, 3, 0> e3;
I'm getting sizeof values of 4, 24, and 12 for e1, e2, and e3.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]