Types of structured bindings.

44 views
Skip to first unread message

Vlad from Moscow

unread,
Jun 4, 2018, 5:40:07 AM6/4/18
to ISO C++ Standard - Discussion
In the paragraph #1 of the section  "11.5 Structured binding declarations" there is written

1. ...If the assignment-expression in the initializer has array type A and no
ref-qualifier is present, e has type cv A and each element is copy-initialized or direct-initialized from the
corresponding element of the assignment-expression as specified by the form of the initializer. ...
corresponding element of the assignment-expression as specified by the form of the initializer. ...

So let's consider the following declarations

    const int a[] = { 10, 20 };
   
auto [first, second] = a;

The type of the identifier a is const int[2]. Thus the variable with the unique name e also should have the type const int[2].

So according to the paragraph #2 of the section

2 If E is an array type with element type T, the number of elements in the identifier-list shall be equal to
the number of elements of E. Each vi is the name of an lvalue that refers to the element i of the array
and whose type is T; the referenced type is T.
the number of elements of E. Each vi is the name of an lvalue that refers to the element i of the array and whose type is T; the referenced type is Tand whose type is T; the referenced type is T.

the names first and second should have the type const int because the element type of  the array e is const int.  

However the actual type of the names is int according to the gcc compiler. 

Either I missed something or the description of the section requires some editions. 

Richard Hodges

unread,
Jun 4, 2018, 5:54:25 AM6/4/18
to std-dis...@isocpp.org
The way I read this was “e has type cv A”, the cv coming from the declaration of auto[…].

In the case above, the cv type is “not const and not volatile”. I didn’t see anything to argue against this in the wording, but then again I might be reading through the eyes of “this is obviously how it should work”.




--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.

Vlad from Moscow

unread,
Jun 4, 2018, 6:39:15 AM6/4/18
to ISO C++ Standard - Discussion

понедельник, 4 июня 2018 г., 13:54:25 UTC+4 пользователь Richard Hodges написал:

On 4 Jun 2018, at 11:40, 'Vlad from Moscow' via ISO C++ Standard - Discussion <std-dis...@isocpp.org> wrote:

In the paragraph #1 of the section  "11.5 Structured binding declarations" there is written

1. ...If the assignment-expression in the initializer has array type A and no
ref-qualifier is present, e has type cv A and each element is copy-initialized or direct-initialized from the
corresponding element of the assignment-expression as specified by the form of the initializer. ...
corresponding element of the assignment-expression as specified by the form of the initializer. ...

So let's consider the following declarations

    const int a[] = { 10, 20 };
   
auto [first, second] = a;

The type of the identifier a is const int[2]. Thus the variable with the unique name e also should have the type const int[2].

So according to the paragraph #2 of the section

2 If E is an array type with element type T, the number of elements in the identifier-list shall be equal to
the number of elements of E. Each vi is the name of an lvalue that refers to the element i of the array
and whose type is T; the referenced type is T.
the number of elements of E. Each vi is the name of an lvalue that refers to the element i of the array and whose type is T; the referenced type is Tand whose type is T; the referenced type is T.

the names first and second should have the type const int because the element type of  the array e is const int.  

However the actual type of the names is int according to the gcc compiler. 

Either I missed something or the description of the section requires some editions. 

The way I read this was “e has type cv A”, the cv coming from the declaration of auto[…].


The cv can come from the decl-specifier-seq. However the type A itself already can be a cv-qualified array type. There is nothing said that the cv-qualifiers of the type A are discarded.

Nicolas Lesser

unread,
Jun 4, 2018, 8:13:28 AM6/4/18
to std-dis...@isocpp.org
No I agree. The type should be const int, and not int. Indeed, on clang, the types are const int.
I don't think it's worth changing the wording, I find it clear enough.

--

Vlad from Moscow

unread,
Jun 4, 2018, 8:26:55 AM6/4/18
to ISO C++ Standard - Discussion
So gcc HEAD 9.0.0 20180601 has a bug does it? Because the following code compiles successfully.

#include <iostream>


int main()

{

   
const int a[] = { 10, 20 };

   
auto [first, second] = a;

   
    std
::cout << first << ", " << second << std::endl;
   
    first
= 1;


    std
::cout << first << ", " << second << std::endl;
}  




понедельник, 4 июня 2018 г., 16:13:28 UTC+4 пользователь Nicolas Lesser написал:

Nicolas Lesser

unread,
Jun 4, 2018, 8:30:21 AM6/4/18
to std-dis...@isocpp.org
I woud say so, yes. Can you file one?

Richard Hodges

unread,
Jun 4, 2018, 8:35:17 AM6/4/18
to std-dis...@isocpp.org
On Mon, 2018-06-04 at 14:11 +0200, Nicolas Lesser wrote:
No I agree. The type should be const int, and not int. Indeed, on clang, the types are const int.
I don't think it's worth changing the wording, I find it clear enough.


In this case I respectfully submit that the standard is incorrect, as it's doing an illogical thing.

in the case of:
auto [x, y] = <anything>

I think it's logical to expect that x and y are mutable, non-volatile copies.

In the case of
auto& [x, y] = <anything>

It's logical to expect that x and y are aliases of the contents of <anything>

Surely?



signature.asc

Nicolas Lesser

unread,
Jun 4, 2018, 10:00:09 AM6/4/18
to std-dis...@isocpp.org
Hmm I see your point. I guess it's for consistency:

const int* a = nullptr;
auto b = a;

Now b is const int*. If we imagine a [] instead of a *, then it would also make sense for the individual elements to be const too. Of course that syntax is imaginary, but I can see why this is the case.

Anyways, that's just what I think.

--

Richard Hodges

unread,
Jun 4, 2018, 10:09:43 AM6/4/18
to std-dis...@isocpp.org
On Mon, 4 Jun 2018 at 15:00, Nicolas Lesser <blitz...@gmail.com> wrote:
Hmm I see your point. I guess it's for consistency:

const int* a = nullptr;
auto b = a;

Now b is const int*. If we imagine a [] instead of a *, then it would also make sense for the individual elements to be const too. Of course that syntax is imaginary, but I can see why this is the case.


Hmm

auto x = <anything>;

results in a mutable, non-volatile copy of the <anything>. Even if the <anything> is a pointer to a const thing. Remember that the pointer itself is a discrete object.

but 

auto [x] = <the same thing>;

sometimes results in a mutable non-volatile copy? I can't imagine any scenario in which this makes sense.

I'll wager you a beer that it's an oversight in the wording.

Nicolas Lesser

unread,
Jun 4, 2018, 10:14:02 AM6/4/18
to std-dis...@isocpp.org
On Mon, Jun 4, 2018 at 4:09 PM Richard Hodges <hodg...@gmail.com> wrote:
Hmm

auto x = <anything>;

results in a mutable, non-volatile copy of the <anything>. Even if the <anything> is a pointer to a const thing. Remember that the pointer itself is a discrete object.

Yeah the pointer is mutable, but not the underlying element. I'm saying that it's the same thing for arrays.
 

but 

auto [x] = <the same thing>;

sometimes results in a mutable non-volatile copy? I can't imagine any scenario in which this makes sense. 
Isn't that always the case when you use auto? Its type depends on the initializer? 

I'll wager you a beer that it's an oversight in the wording. 
okay :)

Nicolas Lesser

unread,
Jun 4, 2018, 3:57:40 PM6/4/18
to std-dis...@isocpp.org
For the regard, the bug is now filed under https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86049

On Mon, Jun 4, 2018 at 11:40 AM 'Vlad from Moscow' via ISO C++ Standard - Discussion <std-dis...@isocpp.org> wrote:
--
Reply all
Reply to author
Forward
0 new messages