Topic: Elements of constant array as constant expressions.


Author: marsh73@mysteray.com ("Marsh J. Ray")
Date: Thu, 1 Jun 2006 14:20:45 GMT
Raw View
Andrzej 'Foxy' D. wrote:
> Could you explain me, why it's impossible to treat an element of constant
> array as a constant expression?
<>
> It's obvious that a compiler can know, what's the value of array[0], isn't
> it? If an array is constant and the index is a constant expression, then
> the value of array[0] could be known at compile-time, treated as a constant
> expression and used e.g. as a template argument.
>
> What was the reason not to allow to use array's elements in this way?

Array initializers, even for const arrays, don't seem to have nearly the
constraints constraints as those for template type arguments. I just
tested this on one compiler (MSVC80), but I don't think this is any
vendor-specific extension.

Consider what the compiler would have to do to instantiate your template
given the following:

 int salesman_optimal_route_distance()
 {
  return 0; /* TODO: exercise for reader */
 }

 int const array[] = { salesman_optimal_route_distance() };

 template<int I>
 struct A
 { };

 int main()
 {
  A<array[0]> a;
 }


- Marsh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Thu, 1 Jun 2006 15:45:34 GMT
Raw View
"Marsh J. Ray" wrote:
> [..]
> Array initializers, even for const arrays, don't seem to have nearly
> the constraints constraints as those for template type arguments. I
> just tested this on one compiler (MSVC80), but I don't think this is
> any vendor-specific extension.

But how is that related to the case when certain things _can_ be
treated as compile-time constants?

> Consider what the compiler would have to do to instantiate your
> template given the following:
>
> int salesman_optimal_route_distance()
> {
> return 0; /* TODO: exercise for reader */
> }
>
> int const array[] = { salesman_optimal_route_distance() };

Why would that demonstrate anything except that it's allowed?  Try
adding

  const int rtc = salesman_optimal_route_distance();

Is that a compile-time constant?  No.  Try

  const int ctc = 42;

Is that a compile-time constant?  Yes.  What conclusions should we
derive from that?

> template<int I>
> struct A
> { };
>
> int main()
> {
> A<array[0]> a;

And change this to

   A<rtc> aa;

What do you make of that?

   A<ctc> aaa;  // should work just fine

> }

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: marsh73@mysteray.com ("Marsh J. Ray")
Date: Thu, 1 Jun 2006 23:52:15 GMT
Raw View
Victor Bazarov wrote:
> "Marsh J. Ray" wrote:
>> [..]
>> Array initializers, even for const arrays, don't seem to have nearly
>> the constraints constraints as those for template type arguments. I
>> just tested this on one compiler (MSVC80), but I don't think this is
>> any vendor-specific extension.
>
> But how is that related to the case when certain things _can_ be
> treated as compile-time constants?

Maybe you can prove that it can be treated as a compile-time constant,
but can you construct a rule which allows what you are asking and show
the standards committee that the implementers across an incredible range
of platforms can teach their compilers to be able to prove that it can
be treated as a compile-time constant?

Also, don't forget that your array may have externally-visible linkage.

<skip>

> What do you make of that?

What I make of it is that the standards committee didn't want to require
a compiler to have the entire content of (possibly large) arrays
available at the time of template instantiation.

- Marsh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Fri, 2 Jun 2006 04:29:54 GMT
Raw View
"Marsh J. Ray" wrote:
> Victor Bazarov wrote:
>> "Marsh J. Ray" wrote:
>>> [..]
>>> Array initializers, even for const arrays, don't seem to have nearly
>>> the constraints constraints as those for template type arguments. I
>>> just tested this on one compiler (MSVC80), but I don't think this is
>>> any vendor-specific extension.
>>
>> But how is that related to the case when certain things _can_ be
>> treated as compile-time constants?
>
> Maybe you can prove that it can be treated as a compile-time constant,
> but can you construct a rule which allows what you are asking and show
> the standards committee that the implementers across an incredible
> range of platforms can teach their compilers to be able to prove that
> it can be treated as a compile-time constant?

Just add 'elements of an array of const' to the list of what a constant
expression "can involve" (in 5.19/1):

"An integral constant-expression can involve only literals (2.13),
 enumerators, const variables, elements of arrays of const, or static
 data members of integral or enumeration types initialized with
 constant expressions (8.5), ..."

> Also, don't forget that your array may have externally-visible
> linkage.

How is linkage playing into that now?

> <skip>
>
>> What do you make of that?
>
> What I make of it is that the standards committee didn't want to
> require a compiler to have the entire content of (possibly large)
> arrays available at the time of template instantiation.

This just doesn't make sense.  What is so different between elements
of an array of const int and a single const it?  If the compiler can
determine that a single int variable can be used in a compile-time
constant expression, there is nothing seriously more difficult to do
that for any element of an array.  The Committee just didn't think of
it, most likely.  Let's hear from somebody on the Committee, shall we?

V


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "David R Tribble" <david@tribble.com>
Date: Fri, 12 May 2006 13:50:50 CST
Raw View
Andrzej 'Foxy' D. wrote:
> Could you explain me, why it's impossible to treat an element of constant
> array as a constant expression? Look at this code:
>
> const int array[] =  { 1 };
>
> template<int I>
> struct A {};
>
> void f() {
>         A<array[0]> a; // !
> }
>
> It's obvious that a compiler can know what's the value of array[0], isn't
> it? If an array is constant and the index is a constant expression, then
> the value of array[0] could be known at compile-time, treated as a constant
> expression and used e.g. as a template argument.
>
> What was the reason not to allow to use array's elements in this way?

Because even though the compiler _could_ know, it is not _required_
to know by the language specification.  Technically, the value of an
array element (const or not) is not a compile-time constant.  I know
this doesn't sound right to some, but defining array elements as const
does not automatically make them compile-time constants.

The same is true of expressions like "abc"[0].

-drt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Fri, 12 May 2006 20:47:46 GMT
Raw View
David R Tribble wrote:
> Andrzej 'Foxy' D. wrote:
>> Could you explain me, why it's impossible to treat an element of
>> constant array as a constant expression? Look at this code:
>>
>> const int array[] =  { 1 };
>>
>> template<int I>
>> struct A {};
>>
>> void f() {
>>         A<array[0]> a; // !
>> }
>>
>> It's obvious that a compiler can know what's the value of array[0],
>> isn't it? If an array is constant and the index is a constant
>> expression, then the value of array[0] could be known at
>> compile-time, treated as a constant expression and used e.g. as a
>> template argument.
>>
>> What was the reason not to allow to use array's elements in this way?
>
> Because even though the compiler _could_ know, it is not _required_
> to know by the language specification.  Technically, the value of an
> array element (const or not) is not a compile-time constant.  I know
> this doesn't sound right to some, but defining array elements as const
> does not automatically make them compile-time constants.
>
> The same is true of expressions like "abc"[0].

I believe Andrzej's question wasn't "is it?" but rather "why isn't it?"
We already know that the language specification doesn't require the
elements of const arrays to be recognized as const expressions.  The
question is _why the hell not_.  I'd like to know as well, BTW.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Lucas Galfaso" <lgalfaso@gmail.com>
Date: Sun, 14 May 2006 22:40:03 CST
Raw View
Hi all,
  This issue has come up in several different way over the years. You
have to think that operator[] is a function, and, even when this
function does not have side effects, the return value of a funcion is
not a compile time constant.

LG

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Maciej Sobczak <no.spam@no.spam.com>
Date: Mon, 15 May 2006 10:39:30 CST
Raw View
Lucas Galfaso wrote:

> You
> have to think that operator[] is a function

It's not how it's defined in 5.2.1/1:

"The expression E1[E2] is identical (by definition) to *((E1)+(E2))."

> the return value of a funcion is
> not a compile time constant.

But *((E1)+(E2)) could be.


--
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Mon, 15 May 2006 11:01:57 CST
Raw View
Lucas Galfaso wrote:
> Hi all,
>   This issue has come up in several different way over the years. You
> have to think that operator[] is a function, and, even when this
> function does not have side effects, the return value of a funcion is
> not a compile time constant.
>

I don't see that you can make that deduction. For basic types (which an
int[] array is), operators are not functions. Otherwise you wouldn't
have logical shortcircuiting, and all the fun with order of evaluation
issues.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Andrzej 'Foxy' D." <foxyprog@_NOSPAM_o2.pl>
Date: Mon, 15 May 2006 15:38:15 CST
Raw View
Victor Bazarov wrote:

> I believe Andrzej's question wasn't "is it?" but rather "why isn't it?"

Exactly. And, what's funny, there haven't been any sufficient answer yet.

--
Pozdrawiam, Andrzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: foxyprog@_NOSPAM_o2.pl ("Andrzej 'Foxy' D.")
Date: Wed, 3 May 2006 15:23:22 GMT
Raw View
Could you explain me, why it's impossible to treat an element of constant
array as a constant expression? Look at this code:

const int array[] =  { 1 };

template<int I>
struct A {};

void f() {
        A<array[0]> a; // !
}

It's obvious that a compiler can know, what's the value of array[0], isn't
it? If an array is constant and the index is a constant expression, then
the value of array[0] could be known at compile-time, treated as a constant
expression and used e.g. as a template argument.

What was the reason not to allow to use array's elements in this way?

--
Pozdrawiam, Andrzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]