Am i just blind? Is "array = array;" allowed?

Discussion in 'C++' started by Johannes Schaub (litb), Aug 27, 2010.

  1. I really can't find where the Standard forbids the following!

    int a[2] = { 1, 2 };
    int b[2];
    b = a;

    I thought somewhere the Standard says that lvalue expressions of array type
    are nonmodifiable, but I can't find it!

    Any insights?
    Johannes Schaub (litb), Aug 27, 2010
    #1
    1. Advertising

  2. Johannes Schaub (litb)

    Goran Pusic Guest

    On Aug 27, 4:02 pm, "Johannes Schaub (litb)" <>
    wrote:
    > I really can't find where the Standard forbids the following!
    >
    >   int a[2] = { 1, 2 };
    >   int b[2];
    >   b = a;
    >
    > I thought somewhere the Standard says that lvalue expressions of array type
    > are nonmodifiable, but I can't find it!


    No idea about what standard might think, but if it did think
    something, it would still sound like a silly arbitrary constraint.
    What would be the rationale to prevent said assignment?

    Goran.
    Goran Pusic, Aug 27, 2010
    #2
    1. Advertising

  3. Johannes Schaub (litb)

    Jonathan Lee Guest

    On Aug 27, 9:02 am, "Johannes Schaub (litb)" <>
    wrote:
    > I really can't find where the Standard forbids the following!
    >
    >   int a[2] = { 1, 2 };
    >   int b[2];
    >   b = a;
    >
    > I thought somewhere the Standard says that lvalue expressions of array type
    > are nonmodifiable, but I can't find it!
    >
    > Any insights?


    In [dcl.array]

    5. [Node: conversions affecting lvalues of array type are described in
    4.2. Objects of array types cannot be modified, see 3.10 -- end note]

    --Jonathan
    Jonathan Lee, Aug 27, 2010
    #3
  4. Jonathan Lee wrote:

    > On Aug 27, 9:02 am, "Johannes Schaub (litb)" <>
    > wrote:
    >> I really can't find where the Standard forbids the following!
    >>
    >> int a[2] = { 1, 2 };
    >> int b[2];
    >> b = a;
    >>
    >> I thought somewhere the Standard says that lvalue expressions of array
    >> type are nonmodifiable, but I can't find it!
    >>
    >> Any insights?

    >
    > In [dcl.array]
    >
    > 5. [Node: conversions affecting lvalues of array type are described in
    > 4.2. Objects of array types cannot be modified, see 3.10 -- end note]
    >


    Sorry, i can't accept a note. I am looking for normative wording. Is there
    any?
    Johannes Schaub (litb), Aug 27, 2010
    #4
  5. * Johannes Schaub (litb), on 27.08.2010 16:31:
    > Jonathan Lee wrote:
    >
    >> On Aug 27, 9:02 am, "Johannes Schaub (litb)"<>
    >> wrote:
    >>> I really can't find where the Standard forbids the following!
    >>>
    >>> int a[2] = { 1, 2 };
    >>> int b[2];
    >>> b = a;
    >>>
    >>> I thought somewhere the Standard says that lvalue expressions of array
    >>> type are nonmodifiable, but I can't find it!
    >>>
    >>> Any insights?

    >>
    >> In [dcl.array]
    >>
    >> 5. [Node: conversions affecting lvalues of array type are described in
    >> 4.2. Objects of array types cannot be modified, see 3.10 -- end note]
    >>

    >
    > Sorry, i can't accept a note. I am looking for normative wording. Is there
    > any?


    I don't think so, but I think it was intended.

    C++98 §5/8 says that an array is converted to pointer when it's used where an
    rvalue is expected.

    Then §5.17/2 talks about the "value" of the right hand side of an assignment.



    Cheers & hth.,

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
    Alf P. Steinbach /Usenet, Aug 27, 2010
    #5
  6. Christian Hackl wrote:

    > Johannes Schaub (litb) ha scritto:
    >
    >> I really can't find where the Standard forbids the following!
    >>
    >> int a[2] = { 1, 2 };
    >> int b[2];
    >> b = a;

    >
    > It should not compile. Does it on your compiler? I guess you are just
    > the victim of some proprietary extension.
    >


    It compiles with my built-in biological compiler. It needs fixing my being
    pointed to a normative text! AHAHAHA
    Johannes Schaub (litb), Aug 27, 2010
    #6
  7. Alf P. Steinbach /Usenet wrote:

    > * Johannes Schaub (litb), on 27.08.2010 16:31:
    >> Jonathan Lee wrote:
    >>
    >>> On Aug 27, 9:02 am, "Johannes Schaub (litb)"<>
    >>> wrote:
    >>>> I really can't find where the Standard forbids the following!
    >>>>
    >>>> int a[2] = { 1, 2 };
    >>>> int b[2];
    >>>> b = a;
    >>>>
    >>>> I thought somewhere the Standard says that lvalue expressions of array
    >>>> type are nonmodifiable, but I can't find it!
    >>>>
    >>>> Any insights?
    >>>
    >>> In [dcl.array]
    >>>
    >>> 5. [Node: conversions affecting lvalues of array type are described in
    >>> 4.2. Objects of array types cannot be modified, see 3.10 -- end note]
    >>>

    >>
    >> Sorry, i can't accept a note. I am looking for normative wording. Is
    >> there any?

    >
    > I don't think so, but I think it was intended.
    >
    > C++98 §5/8 says that an array is converted to pointer when it's used where
    > an rvalue is expected.
    >
    > Then §5.17/2 talks about the "value" of the right hand side of an
    > assignment.
    >


    Ohh i see now. So i guess it does the array-to-pointer conversion of the
    right side, and then tries to convert "T*" to "T[N]" but since there is no
    such implicit conversion, it fails hard. Thanks for the insights
    Johannes Schaub (litb), Aug 27, 2010
    #7
  8. Goran Pusic <> wrote:
    > On Aug 27, 4:02 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> I really can't find where the Standard forbids the following!
    >>
    >>   int a[2] = { 1, 2 };
    >>   int b[2];
    >>   b = a;
    >>
    >> I thought somewhere the Standard says that lvalue expressions of array type
    >> are nonmodifiable, but I can't find it!

    >
    > No idea about what standard might think, but if it did think
    > something, it would still sound like a silly arbitrary constraint.
    > What would be the rationale to prevent said assignment?


    It's not arbitrary at all, and there is a perfectly good rationale
    which can be derived from the definition of arrays.

    Arrays effectively act as const pointers (in other words "int* const"),
    the only exception being that the sizeof() operator returns the space
    taken by the entire array rather than the size of a pointer. (I know this
    is simplifying quite a lot, and there are probably other examples where
    they don't actually act like const pointers, but you get the idea.)

    So you can think of "b = a;" as the attempt to modify 'b' to make it
    point to the same place as 'a' is pointing to (because that's what pointer
    assignment does). However, 'b' is const, so you can't modify it to point
    anywhere else.

    Of course one could argue that the language should make an exception
    to this general principle in the case where you are assigning an array to
    another of the same type and size, and make it instead assign the contents
    of the array to the other array. I don't know, however, if the
    standardization committee had a reason to not impose such an exception
    to the general rule (and we are probably talking about the C standardization
    committee here, as this limitation is probably coming from C).
    Juha Nieminen, Aug 27, 2010
    #8
  9. Juha Nieminen wrote:

    > Goran Pusic <> wrote:
    >> On Aug 27, 4:02 pm, "Johannes Schaub (litb)" <>
    >> wrote:
    >>> I really can't find where the Standard forbids the following!
    >>>
    >>> int a[2] = { 1, 2 };
    >>> int b[2];
    >>> b = a;
    >>>
    >>> I thought somewhere the Standard says that lvalue expressions of array
    >>> type are nonmodifiable, but I can't find it!

    >>
    >> No idea about what standard might think, but if it did think
    >> something, it would still sound like a silly arbitrary constraint.
    >> What would be the rationale to prevent said assignment?

    >
    > It's not arbitrary at all, and there is a perfectly good rationale
    > which can be derived from the definition of arrays.
    >
    > Arrays effectively act as const pointers (in other words "int* const"),
    > the only exception being that the sizeof() operator returns the space
    > taken by the entire array rather than the size of a pointer. (I know this
    > is simplifying quite a lot, and there are probably other examples where
    > they don't actually act like const pointers, but you get the idea.)
    >
    > So you can think of "b = a;" as the attempt to modify 'b' to make it
    > point to the same place as 'a' is pointing to (because that's what pointer
    > assignment does). However, 'b' is const, so you can't modify it to point
    > anywhere else.
    >
    > Of course one could argue that the language should make an exception
    > to this general principle in the case where you are assigning an array to
    > another of the same type and size, and make it instead assign the contents
    > of the array to the other array. I don't know, however, if the
    > standardization committee had a reason to not impose such an exception
    > to the general rule (and we are probably talking about the C
    > standardization committee here, as this limitation is probably coming from
    > C).


    I would argue the entire other way around, and make the pointer behavior a
    "special case":

    >>>>

    Arrays are a container for N elements of the same type. In cases where array
    elements need to be addressed, a pointer to the array is created.

    Assigning an array to another array will take N elements from the source
    array and copy it over.
    <<<<<<<


    You can apply your same sayings to any variable:

    >>>>>>

    In general, an "int" variable effectively acts as a const pointer (in other
    words: "int *const") the only exception being that sizeof... .

    So you can think of "a = b;" as the attempt to modify "a" to make it point
    to the same place as "b" is pointing to (because thats what pointer
    assignment does). However, 'a' is const, so you can't modify it to point
    anywhere else.

    Of course, one could argue .... and make it instead assign the contents of
    the int to the other int. I don't know, however, ... .
    <<<<<<
    Johannes Schaub (litb), Aug 27, 2010
    #9
  10. Johannes Schaub (litb) wrote:
    >> I don't think so, but I think it was intended.
    >>
    >> C++98 §5/8 says that an array is converted to pointer when it's used where
    >> an rvalue is expected.
    >>
    >> Then §5.17/2 talks about the "value" of the right hand side of an
    >> assignment.
    >>

    >
    > Ohh i see now. So i guess it does the array-to-pointer conversion of the
    > right side, and then tries to convert "T*" to "T[N]" but since there is no
    > such implicit conversion, it fails hard. Thanks for the insights


    Well, I would also expect this assignment to be "disabled" in C++ by a
    different rule: array-to-pointer conversion on the RHS operand.

    The 5/9 does indeed say that array-to-pointer conversion is applied when
    an rvalue operand is expected.

    Descriptions of various operators normally explicitly state whether a
    given operand is expected/required to be an lvalue or an rvalue.
    However, the description of the assignment operator only has the
    requirements for the LHS operand. No requirement for the RHS is present
    there.

    So, where does it say that built-in assignment expects an rvalue on the
    RHS??? I don't see it stated anywhere.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Aug 27, 2010
    #10
  11. "Johannes Schaub (litb)" <> wrote in message
    news:i58gdf$hpd$02$-online.com...
    > I really can't find where the Standard forbids the following!
    >
    > int a[2] = { 1, 2 };
    > int b[2];
    > b = a;
    >
    > I thought somewhere the Standard says that lvalue expressions of array
    > type
    > are nonmodifiable, but I can't find it!
    >
    > Any insights?


    Use the STL as its there for reason.

    #include <vector>

    std::vector<int> a, b;
    a[1] = 1;
    a[2] = 2;

    b = a;

    will work as desired
    Sprechen sie von C++, Aug 27, 2010
    #11
  12. Sprechen sie von C++ <>, on 27/08/2010 15:40:05, wrote:

    > "Johannes Schaub (litb)" <> wrote in message
    > news:i58gdf$hpd$02$-online.com...
    >> I really can't find where the Standard forbids the following!
    >>
    >> int a[2] = { 1, 2 };
    >> int b[2];
    >> b = a;
    >>
    >> I thought somewhere the Standard says that lvalue expressions of array
    >> type
    >> are nonmodifiable, but I can't find it!
    >>
    >> Any insights?

    >
    > Use the STL as its there for reason.
    >
    > #include <vector>
    >
    > std::vector<int> a, b;
    > a[1] = 1;
    > a[2] = 2;
    >
    > b = a;
    >
    > will work as desired


    Apart that you missed the point, you posted non working code - that
    happens to me too, but somebody always has to point it out, sorry.

    Needs push_back() instead of subscript operators or else a properly
    sized "a" before assigning the elements as you did. And main() to wrap
    the code ;-)

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
    Francesco S. Carta, Aug 28, 2010
    #12
  13. Johannes Schaub (litb)

    James Kanze Guest

    On Aug 27, 5:17 pm, Juha Nieminen <> wrote:
    > Goran Pusic <> wrote:
    > > On Aug 27, 4:02 pm, "Johannes Schaub (litb)" <>
    > > wrote:
    > >> I really can't find where the Standard forbids the following!


    > >> int a[2] = { 1, 2 };
    > >> int b[2];
    > >> b = a;


    > >> I thought somewhere the Standard says that lvalue
    > >> expressions of array type are nonmodifiable, but I can't
    > >> find it!


    > > No idea about what standard might think, but if it did think
    > > something, it would still sound like a silly arbitrary
    > > constraint. What would be the rationale to prevent said
    > > assignment?


    There is none. Whether something is unmodifiable or not depends
    on the object, not the lvalue expression used to modify it. And
    arrays (at least non-const arrays) are certainly modifiable.

    > It's not arbitrary at all, and there is a perfectly good
    > rationale which can be derived from the definition of arrays.


    > Arrays effectively act as const pointers (in other words "int*
    > const"), the only exception being that the sizeof() operator
    > returns the space taken by the entire array rather than the
    > size of a pointer. (I know this is simplifying quite a lot,
    > and there are probably other examples where they don't
    > actually act like const pointers, but you get the idea.)


    It's misleading, if not actually false. Arrays always act as
    arrays. One characteristic of an array, however, is that it can
    be implicitly converted into a pointer to the first element.
    Not a const pointer, by the way, but since the result of the
    conversion is an rvalue, there's no way of accessing the
    resulting temporary in order to modify it.

    The reason a = b is illegal if a is an array type is that
    assignment to anything but a class type requires an rvalue on
    the right hand side, and according to §5.2/8:

    Whenever an lvalue expression appears as an operand of
    an operator that expects an rvalue for that operand, the
    lvalue-to-rvalue (4.1), array-to-pointer (4.2), or
    function-to-pointer (4.3) standard conversions are
    applied to convert the expression to an rvalue.

    Thus, any array type to the right of a built-in assignment is
    converted to a pointer. And there's no way to convert this
    pointer back to the array type required by the left hand side.

    Note that this is only true for built-in assignment. If the
    left hand side is a class type with an assignment operator which
    takes a reference, then an rvalue is not expected, none of the
    conversions in the cited paragraph take place, and if the array
    type can be used to initialize the reference, it will be.

    > So you can think of "b = a;" as the attempt to modify 'b' to
    > make it point to the same place as 'a' is pointing to (because
    > that's what pointer assignment does). However, 'b' is const,
    > so you can't modify it to point anywhere else.


    IIRC, C did say something along those lines---that both the left
    side and the right side of assignments underwent the array to
    pointer conversion. And since the results of a conversion
    (other than to a reference type in C++) is an rvalue, the
    requirement that the left hand side be an lvalue was violated.
    (But arrays still don't "effectively act like pointers". Even
    in C, array types are very different from pointers, and there is
    still only an implicit conversion.)

    The C++ rules are slightly different, although the differences
    generally can't be seen without the use of features not
    available in C. The most obvious case:

    struct Toto
    {
    Toto& operator=(int (&a)[5]);
    };

    Toto a;
    int b[5];

    a = b; // legal...

    A somewhat more surprising one:

    int (&f())[5];
    /*
    probably better written:
    typedef int Array[5];
    Array& f();
    */
    int a[5];
    a = f(); // legal! ?

    To be frank, this one surprises me so much that I suspect that
    there's still a constraint somewhere that I've missed. Perhaps
    the combination of [§5.17/3] "If the left operand is not of
    class type, the expression is implicitly converted (clause 4) to
    the cv-unqualified type of the left operand" and/or [§5/6] "If
    an expression initially has the type “reference to T” (8.3.2,
    8.5.3), the type is adjusted to “T” prior to any further
    analysis, the expression designates the object or function
    denoted by the reference, and the expression is an lvalue" imply
    that the "reference" in the type is stripped off before the
    check for rvalue-ness is applied.

    > Of course one could argue that the language should make an
    > exception to this general principle in the case where you are
    > assigning an array to another of the same type and size, and
    > make it instead assign the contents of the array to the other
    > array. I don't know, however, if the standardization committee
    > had a reason to not impose such an exception to the general
    > rule (and we are probably talking about the C standardization
    > committee here, as this limitation is probably coming from C).


    The C++ committee designed the rules to be compatible with
    standard C. (Allowing array assignment would have been a simple
    extension, but it wouldn't really have bought much unless they
    also allows passing arrays to functions, which would have broken
    compatibility completely.) The C committee designed their rules
    to be compatible with all of the existing implementations, which
    were based on the rules defined in K&R1. Which in turn derived
    from B, which didn't have any types---everything was a "word",
    and when you declared the dimensions of an array, the compiler
    allocated an anonymous array, and put its address in the named
    variable (which had type word).

    --
    James Kanze
    James Kanze, Aug 28, 2010
    #13
  14. Johannes Schaub (litb)

    James Kanze Guest

    On Aug 27, 3:24 pm, Jonathan Lee <> wrote:
    > On Aug 27, 9:02 am, "Johannes Schaub (litb)" <>
    > wrote:


    > > I really can't find where the Standard forbids the following!


    > > int a[2] = { 1, 2 };
    > > int b[2];
    > > b = a;


    > > I thought somewhere the Standard says that lvalue
    > > expressions of array type are nonmodifiable, but I can't
    > > find it!


    > > Any insights?


    > In [dcl.array]


    > 5. [Node: conversions affecting lvalues of array type are described in
    > 4.2. Objects of array types cannot be modified, see 3.10 -- end note]


    That's a note, so it's not normative. And it's obviously wrong,
    since objects of array types certainly can be modified; the
    programs I'm working on do it all the time.

    See my response to Juha for a very formal description of what
    the standard says. But it all boils down to the fact that an
    array on the right hand side implicitly converts to a pointer,
    and you can't assign a pointer to an array (C++), or a pointer
    to the rvalue resulting from an array to pointer conversion (C,
    *if* I'm remembering C correctly).

    --
    James Kanze
    James Kanze, Aug 28, 2010
    #14
  15. Johannes Schaub (litb)

    Goran Pusic Guest

    On Aug 27, 6:17 pm, Juha Nieminen <> wrote:
    > Goran Pusic <> wrote:
    > > On Aug 27, 4:02 pm, "Johannes Schaub (litb)" <>
    > > wrote:
    > >> I really can't find where the Standard forbids the following!

    >
    > >>   int a[2] = { 1, 2 };
    > >>   int b[2];
    > >>   b = a;

    >
    > >> I thought somewhere the Standard says that lvalue expressions of array type
    > >> are nonmodifiable, but I can't find it!

    >
    > > No idea about what standard might think, but if it did think
    > > something, it would still sound like a silly arbitrary constraint.
    > > What would be the rationale to prevent said assignment?

    >
    >   It's not arbitrary at all, and there is a perfectly good rationale
    > which can be derived from the definition of arrays.
    >
    >   Arrays effectively act as const pointers (in other words "int* const"),
    > the only exception being that the sizeof() operator returns the space
    > taken by the entire array rather than the size of a pointer. (I know this
    > is simplifying quite a lot, and there are probably other examples where
    > they don't actually act like const pointers, but you get the idea.)


    Well, they act as such but AFAIK, aren't it. Ah, I see it's all
    explained already. Never mind then.

    Goran.
    Goran Pusic, Aug 30, 2010
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roy

    Am I blind?

    Roy, Feb 3, 2005, in forum: ASP .Net
    Replies:
    5
    Views:
    497
  2. Frogleg

    Free blind browser?

    Frogleg, Sep 2, 2004, in forum: HTML
    Replies:
    52
    Views:
    3,037
    Spartanicus
    Sep 10, 2004
  3. aa
    Replies:
    75
    Views:
    2,174
  4. Hats
    Replies:
    0
    Views:
    499
  5. Iñaki Baz Castillo
    Replies:
    13
    Views:
    467
    Iñaki Baz Castillo
    May 1, 2011
Loading...

Share This Page