Shall structured binding to a copy of a const c-array be const?











up vote
18
down vote

favorite
3












Consider this code (demo):



#include <tuple>
#include <type_traits>

struct Ag{int i;int j;};
using T = std::tuple<int,int>;
using Ar = int[2];

const Ag ag {};
const T t {};
const Ar ar {};

void bind_ag(){
auto [i,j] = ag;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_t(){
auto [i,j] = t;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_ar(){
auto [i,j] = ar;
static_assert(std::is_same_v<decltype((i)),int&>); //For GCC
static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
}


A structured binding to a copy of a const c-array are declared const by Clang and non-const by GCC.



The behavior of GCC for c-array is consistent with the behavior observed for aggregate or tuple-like types.



On the other hand from my reading of the standard, I suppose Clang follows what is written. In [dcl.struct.bind]/1 e has type cv A where A is the type of the initializer expression and the cv is the cv-qualifier of the structured binding declaration. And the type of the initializer expression ar is accordingly to [expr.type]/1 const int[2].



What should be expected? My opinion is that Clang follows the standard. On the other hand I feel the intent was that the behaviors for array, aggregate and tuple-like types were equivalent.










share|improve this question




















  • 1




    Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
    – Daniel Langr
    4 hours ago








  • 3




    gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
    – cpplearner
    3 hours ago















up vote
18
down vote

favorite
3












Consider this code (demo):



#include <tuple>
#include <type_traits>

struct Ag{int i;int j;};
using T = std::tuple<int,int>;
using Ar = int[2];

const Ag ag {};
const T t {};
const Ar ar {};

void bind_ag(){
auto [i,j] = ag;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_t(){
auto [i,j] = t;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_ar(){
auto [i,j] = ar;
static_assert(std::is_same_v<decltype((i)),int&>); //For GCC
static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
}


A structured binding to a copy of a const c-array are declared const by Clang and non-const by GCC.



The behavior of GCC for c-array is consistent with the behavior observed for aggregate or tuple-like types.



On the other hand from my reading of the standard, I suppose Clang follows what is written. In [dcl.struct.bind]/1 e has type cv A where A is the type of the initializer expression and the cv is the cv-qualifier of the structured binding declaration. And the type of the initializer expression ar is accordingly to [expr.type]/1 const int[2].



What should be expected? My opinion is that Clang follows the standard. On the other hand I feel the intent was that the behaviors for array, aggregate and tuple-like types were equivalent.










share|improve this question




















  • 1




    Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
    – Daniel Langr
    4 hours ago








  • 3




    gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
    – cpplearner
    3 hours ago













up vote
18
down vote

favorite
3









up vote
18
down vote

favorite
3






3





Consider this code (demo):



#include <tuple>
#include <type_traits>

struct Ag{int i;int j;};
using T = std::tuple<int,int>;
using Ar = int[2];

const Ag ag {};
const T t {};
const Ar ar {};

void bind_ag(){
auto [i,j] = ag;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_t(){
auto [i,j] = t;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_ar(){
auto [i,j] = ar;
static_assert(std::is_same_v<decltype((i)),int&>); //For GCC
static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
}


A structured binding to a copy of a const c-array are declared const by Clang and non-const by GCC.



The behavior of GCC for c-array is consistent with the behavior observed for aggregate or tuple-like types.



On the other hand from my reading of the standard, I suppose Clang follows what is written. In [dcl.struct.bind]/1 e has type cv A where A is the type of the initializer expression and the cv is the cv-qualifier of the structured binding declaration. And the type of the initializer expression ar is accordingly to [expr.type]/1 const int[2].



What should be expected? My opinion is that Clang follows the standard. On the other hand I feel the intent was that the behaviors for array, aggregate and tuple-like types were equivalent.










share|improve this question















Consider this code (demo):



#include <tuple>
#include <type_traits>

struct Ag{int i;int j;};
using T = std::tuple<int,int>;
using Ar = int[2];

const Ag ag {};
const T t {};
const Ar ar {};

void bind_ag(){
auto [i,j] = ag;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_t(){
auto [i,j] = t;
static_assert(std::is_same_v<decltype((i)),int&>);
}
void bind_ar(){
auto [i,j] = ar;
static_assert(std::is_same_v<decltype((i)),int&>); //For GCC
static_assert(std::is_same_v<decltype((i)),const int&>); //For Clang (and standard?)
}


A structured binding to a copy of a const c-array are declared const by Clang and non-const by GCC.



The behavior of GCC for c-array is consistent with the behavior observed for aggregate or tuple-like types.



On the other hand from my reading of the standard, I suppose Clang follows what is written. In [dcl.struct.bind]/1 e has type cv A where A is the type of the initializer expression and the cv is the cv-qualifier of the structured binding declaration. And the type of the initializer expression ar is accordingly to [expr.type]/1 const int[2].



What should be expected? My opinion is that Clang follows the standard. On the other hand I feel the intent was that the behaviors for array, aggregate and tuple-like types were equivalent.







c++ language-lawyer c++17 structured-bindings






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 4 hours ago

























asked 4 hours ago









Oliv

7,9631854




7,9631854








  • 1




    Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
    – Daniel Langr
    4 hours ago








  • 3




    gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
    – cpplearner
    3 hours ago














  • 1




    Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
    – Daniel Langr
    4 hours ago








  • 3




    gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
    – cpplearner
    3 hours ago








1




1




Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
– Daniel Langr
4 hours ago






Isn't this note related: eel.is/c++draft/dcl.struct.bind#3.note-1?
– Daniel Langr
4 hours ago






3




3




gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
– cpplearner
3 hours ago




gcc.gnu.org/bugzilla/show_bug.cgi?id=86049
– cpplearner
3 hours ago












2 Answers
2






active

oldest

votes

















up vote
9
down vote













The wording of the standard in [dcl.struct.bind] says:




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.




We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.



However, as Richard Smith points out in gcc bug 80649:




I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.




That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.






share|improve this answer





















  • The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
    – Lightness Races in Orbit
    2 hours ago








  • 2




    @LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
    – Barry
    2 hours ago










  • Mm, I could be persuaded by that.
    – Lightness Races in Orbit
    2 hours ago










  • Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
    – Oliv
    1 hour ago


















up vote
4
down vote













In my opinion, GCC is correct (and, as you pointed out, more intuitive), though certainly some people disagree.



The decl-specifier-seq ("auto") has no cv-qualifiers (that is, you did not write const auto), and that should be what is considered as cv when deciding what qualifiers to put on the bindings.




[dcl.struct.bind]/1: [..] Let cv denote the cv-qualifiers in the decl-specifier-seq. [..]



[dcl.struct.bind]/3: 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. [ Note: The top-level cv-qualifiers of T are cv. — end note ] [..]




Like you, Clang devs have interpreted the auto here as having cv-qualification of const, because the type inferred by it is const Ag. But I see no standard justification for that interpretation.






share|improve this answer





















  • Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
    – Rakete1111
    2 hours ago










  • @Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
    – Lightness Races in Orbit
    2 hours ago












  • I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
    – Rakete1111
    1 hour ago










  • @Rakete1111 Okay, that's convincing.
    – Lightness Races in Orbit
    1 hour ago










  • Either way, that note must go or we should actually fix this inconsistency.
    – Rakete1111
    1 hour ago











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53726135%2fshall-structured-binding-to-a-copy-of-a-const-c-array-be-const%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
9
down vote













The wording of the standard in [dcl.struct.bind] says:




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.




We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.



However, as Richard Smith points out in gcc bug 80649:




I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.




That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.






share|improve this answer





















  • The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
    – Lightness Races in Orbit
    2 hours ago








  • 2




    @LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
    – Barry
    2 hours ago










  • Mm, I could be persuaded by that.
    – Lightness Races in Orbit
    2 hours ago










  • Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
    – Oliv
    1 hour ago















up vote
9
down vote













The wording of the standard in [dcl.struct.bind] says:




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.




We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.



However, as Richard Smith points out in gcc bug 80649:




I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.




That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.






share|improve this answer





















  • The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
    – Lightness Races in Orbit
    2 hours ago








  • 2




    @LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
    – Barry
    2 hours ago










  • Mm, I could be persuaded by that.
    – Lightness Races in Orbit
    2 hours ago










  • Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
    – Oliv
    1 hour ago













up vote
9
down vote










up vote
9
down vote









The wording of the standard in [dcl.struct.bind] says:




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.




We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.



However, as Richard Smith points out in gcc bug 80649:




I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.




That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.






share|improve this answer












The wording of the standard in [dcl.struct.bind] says:




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.




We have auto [i,j] = ar;, ar has array type const int[2], and the wording of the standard makes it clear that e has type const int[2]. Thus, per the wording, each binding references the element type - which is const int. Clang is technically correct.



However, as Richard Smith points out in gcc bug 80649:




I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.




That seems right. When you write auto x = y; you'd certainly expect x to not be top-level const, but here we have a situation where it still is. I don't think there's a Core issue open for this yet, but there should be.







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









Barry

175k18298553




175k18298553












  • The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
    – Lightness Races in Orbit
    2 hours ago








  • 2




    @LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
    – Barry
    2 hours ago










  • Mm, I could be persuaded by that.
    – Lightness Races in Orbit
    2 hours ago










  • Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
    – Oliv
    1 hour ago


















  • The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
    – Lightness Races in Orbit
    2 hours ago








  • 2




    @LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
    – Barry
    2 hours ago










  • Mm, I could be persuaded by that.
    – Lightness Races in Orbit
    2 hours ago










  • Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
    – Oliv
    1 hour ago
















The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
– Lightness Races in Orbit
2 hours ago






The cv-qualification cv comes from the decl-specifier-seq ("auto") not the initialiser ("ar"), no? Unless it's saying that the qualifiers on A are merged into cv. But I don't follow why that would be the case; without a ref-qualifier, why would it want to maintain constness? It doesn't do that anywhere else.
– Lightness Races in Orbit
2 hours ago






2




2




@LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
– Barry
2 hours ago




@LightnessRacesinOrbit It does - but A is an array of const, so cv A is still an array of const. I don't think we want to maintain constness, hence Core issue.
– Barry
2 hours ago












Mm, I could be persuaded by that.
– Lightness Races in Orbit
2 hours ago




Mm, I could be persuaded by that.
– Lightness Races in Orbit
2 hours ago












Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
– Oliv
1 hour ago




Thank you, viewed the comment I think I am going to takes both answer (I am not in a comfortable to put a thick on one or the other).
– Oliv
1 hour ago












up vote
4
down vote













In my opinion, GCC is correct (and, as you pointed out, more intuitive), though certainly some people disagree.



The decl-specifier-seq ("auto") has no cv-qualifiers (that is, you did not write const auto), and that should be what is considered as cv when deciding what qualifiers to put on the bindings.




[dcl.struct.bind]/1: [..] Let cv denote the cv-qualifiers in the decl-specifier-seq. [..]



[dcl.struct.bind]/3: 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. [ Note: The top-level cv-qualifiers of T are cv. — end note ] [..]




Like you, Clang devs have interpreted the auto here as having cv-qualification of const, because the type inferred by it is const Ag. But I see no standard justification for that interpretation.






share|improve this answer





















  • Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
    – Rakete1111
    2 hours ago










  • @Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
    – Lightness Races in Orbit
    2 hours ago












  • I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
    – Rakete1111
    1 hour ago










  • @Rakete1111 Okay, that's convincing.
    – Lightness Races in Orbit
    1 hour ago










  • Either way, that note must go or we should actually fix this inconsistency.
    – Rakete1111
    1 hour ago















up vote
4
down vote













In my opinion, GCC is correct (and, as you pointed out, more intuitive), though certainly some people disagree.



The decl-specifier-seq ("auto") has no cv-qualifiers (that is, you did not write const auto), and that should be what is considered as cv when deciding what qualifiers to put on the bindings.




[dcl.struct.bind]/1: [..] Let cv denote the cv-qualifiers in the decl-specifier-seq. [..]



[dcl.struct.bind]/3: 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. [ Note: The top-level cv-qualifiers of T are cv. — end note ] [..]




Like you, Clang devs have interpreted the auto here as having cv-qualification of const, because the type inferred by it is const Ag. But I see no standard justification for that interpretation.






share|improve this answer





















  • Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
    – Rakete1111
    2 hours ago










  • @Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
    – Lightness Races in Orbit
    2 hours ago












  • I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
    – Rakete1111
    1 hour ago










  • @Rakete1111 Okay, that's convincing.
    – Lightness Races in Orbit
    1 hour ago










  • Either way, that note must go or we should actually fix this inconsistency.
    – Rakete1111
    1 hour ago













up vote
4
down vote










up vote
4
down vote









In my opinion, GCC is correct (and, as you pointed out, more intuitive), though certainly some people disagree.



The decl-specifier-seq ("auto") has no cv-qualifiers (that is, you did not write const auto), and that should be what is considered as cv when deciding what qualifiers to put on the bindings.




[dcl.struct.bind]/1: [..] Let cv denote the cv-qualifiers in the decl-specifier-seq. [..]



[dcl.struct.bind]/3: 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. [ Note: The top-level cv-qualifiers of T are cv. — end note ] [..]




Like you, Clang devs have interpreted the auto here as having cv-qualification of const, because the type inferred by it is const Ag. But I see no standard justification for that interpretation.






share|improve this answer












In my opinion, GCC is correct (and, as you pointed out, more intuitive), though certainly some people disagree.



The decl-specifier-seq ("auto") has no cv-qualifiers (that is, you did not write const auto), and that should be what is considered as cv when deciding what qualifiers to put on the bindings.




[dcl.struct.bind]/1: [..] Let cv denote the cv-qualifiers in the decl-specifier-seq. [..]



[dcl.struct.bind]/3: 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. [ Note: The top-level cv-qualifiers of T are cv. — end note ] [..]




Like you, Clang devs have interpreted the auto here as having cv-qualification of const, because the type inferred by it is const Ag. But I see no standard justification for that interpretation.







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









Lightness Races in Orbit

281k51453769




281k51453769












  • Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
    – Rakete1111
    2 hours ago










  • @Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
    – Lightness Races in Orbit
    2 hours ago












  • I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
    – Rakete1111
    1 hour ago










  • @Rakete1111 Okay, that's convincing.
    – Lightness Races in Orbit
    1 hour ago










  • Either way, that note must go or we should actually fix this inconsistency.
    – Rakete1111
    1 hour ago


















  • Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
    – Rakete1111
    2 hours ago










  • @Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
    – Lightness Races in Orbit
    2 hours ago












  • I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
    – Rakete1111
    1 hour ago










  • @Rakete1111 Okay, that's convincing.
    – Lightness Races in Orbit
    1 hour ago










  • Either way, that note must go or we should actually fix this inconsistency.
    – Rakete1111
    1 hour ago
















Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
– Rakete1111
2 hours ago




Yeah, that note is misleading. Do you agree that the type of the underlying object is const int[2]? Then you should also agree that the element type T of the array is const int, and not int.
– Rakete1111
2 hours ago












@Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
– Lightness Races in Orbit
2 hours ago






@Rakete1111 Yes, but the cv-qualifiers in the decl-specifier-seq, and thus cv, are none-ness. And it is cv that determines the cv-qualifiers of T. Or it could be that I'm being thrown off by the phrase "top-level".
– Lightness Races in Orbit
2 hours ago














I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
– Rakete1111
1 hour ago




I agree. But cv is not the only cv-qualifier that affects the type of T. For another example: If U is const int, then saying that the type of something is cv U with cv being empty, it doesn't mean that U is not const.
– Rakete1111
1 hour ago












@Rakete1111 Okay, that's convincing.
– Lightness Races in Orbit
1 hour ago




@Rakete1111 Okay, that's convincing.
– Lightness Races in Orbit
1 hour ago












Either way, that note must go or we should actually fix this inconsistency.
– Rakete1111
1 hour ago




Either way, that note must go or we should actually fix this inconsistency.
– Rakete1111
1 hour ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53726135%2fshall-structured-binding-to-a-copy-of-a-const-c-array-be-const%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

Mangá

 ⁒  ․,‪⁊‑⁙ ⁖, ⁇‒※‌, †,⁖‗‌⁝    ‾‸⁘,‖⁔⁣,⁂‾
”‑,‥–,‬ ,⁀‹⁋‴⁑ ‒ ,‴⁋”‼ ⁨,‷⁔„ ‰′,‐‚ ‥‡‎“‷⁃⁨⁅⁣,⁔
⁇‘⁔⁡⁏⁌⁡‿‶‏⁨ ⁣⁕⁖⁨⁩⁥‽⁀  ‴‬⁜‟ ⁃‣‧⁕‮ …‍⁨‴ ⁩,⁚⁖‫ ,‵ ⁀,‮⁝‣‣ ⁑  ⁂– ․, ‾‽ ‏⁁“⁗‸ ‾… ‹‡⁌⁎‸‘ ‡⁏⁌‪ ‵⁛ ‎⁨ ―⁦⁤⁄⁕