Local reference to std::cout captured by lambda without asking for it












33















Have I lost my mind? Was this always permitted?



#include <iostream>

int main()
{
auto& os = std::cout;

auto write = ()
{
os << "whatn";
};

write();
}


I'm using:




Apple LLVM version 10.0.0 (clang-1000.10.44.4)

Target: x86_64-apple-darwin17.7.0




Though also see on Coliru:



(live demo)



I always thought an empty capture would not capture anything.



Indeed, MSDN says:




An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.




Further research suggests that this is in fact okay for capturing const things (which I also didn't know, but whatever), but os is not const (no reference is! though it is immutable…).



I came across this when turning on -Wextra and noticing that Clang thought a &os capture (which is present in my real code) was unnecessary. Removing it I was staggered to find the build worked.










share|improve this question




















  • 2





    possible duplicate: stackoverflow.com/questions/43827651/…

    – papagaga
    Nov 21 '18 at 15:26






  • 4





    Oddly works with gcc 8.2...

    – Matthieu Brucher
    Nov 21 '18 at 15:27






  • 8





    Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

    – Quentin
    Nov 21 '18 at 15:30






  • 6





    There's a defect report opened covering that case and it seem not restricted for std::cout

    – Jans
    Nov 21 '18 at 15:56








  • 3





    @Jans and that is worthy of an answer!

    – SergeyA
    Nov 21 '18 at 16:07
















33















Have I lost my mind? Was this always permitted?



#include <iostream>

int main()
{
auto& os = std::cout;

auto write = ()
{
os << "whatn";
};

write();
}


I'm using:




Apple LLVM version 10.0.0 (clang-1000.10.44.4)

Target: x86_64-apple-darwin17.7.0




Though also see on Coliru:



(live demo)



I always thought an empty capture would not capture anything.



Indeed, MSDN says:




An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.




Further research suggests that this is in fact okay for capturing const things (which I also didn't know, but whatever), but os is not const (no reference is! though it is immutable…).



I came across this when turning on -Wextra and noticing that Clang thought a &os capture (which is present in my real code) was unnecessary. Removing it I was staggered to find the build worked.










share|improve this question




















  • 2





    possible duplicate: stackoverflow.com/questions/43827651/…

    – papagaga
    Nov 21 '18 at 15:26






  • 4





    Oddly works with gcc 8.2...

    – Matthieu Brucher
    Nov 21 '18 at 15:27






  • 8





    Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

    – Quentin
    Nov 21 '18 at 15:30






  • 6





    There's a defect report opened covering that case and it seem not restricted for std::cout

    – Jans
    Nov 21 '18 at 15:56








  • 3





    @Jans and that is worthy of an answer!

    – SergeyA
    Nov 21 '18 at 16:07














33












33








33


1






Have I lost my mind? Was this always permitted?



#include <iostream>

int main()
{
auto& os = std::cout;

auto write = ()
{
os << "whatn";
};

write();
}


I'm using:




Apple LLVM version 10.0.0 (clang-1000.10.44.4)

Target: x86_64-apple-darwin17.7.0




Though also see on Coliru:



(live demo)



I always thought an empty capture would not capture anything.



Indeed, MSDN says:




An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.




Further research suggests that this is in fact okay for capturing const things (which I also didn't know, but whatever), but os is not const (no reference is! though it is immutable…).



I came across this when turning on -Wextra and noticing that Clang thought a &os capture (which is present in my real code) was unnecessary. Removing it I was staggered to find the build worked.










share|improve this question
















Have I lost my mind? Was this always permitted?



#include <iostream>

int main()
{
auto& os = std::cout;

auto write = ()
{
os << "whatn";
};

write();
}


I'm using:




Apple LLVM version 10.0.0 (clang-1000.10.44.4)

Target: x86_64-apple-darwin17.7.0




Though also see on Coliru:



(live demo)



I always thought an empty capture would not capture anything.



Indeed, MSDN says:




An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.




Further research suggests that this is in fact okay for capturing const things (which I also didn't know, but whatever), but os is not const (no reference is! though it is immutable…).



I came across this when turning on -Wextra and noticing that Clang thought a &os capture (which is present in my real code) was unnecessary. Removing it I was staggered to find the build worked.







c++ lambda language-lawyer c++17






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 19:10









curiousguy

4,56123044




4,56123044










asked Nov 21 '18 at 15:24









Lightness Races in OrbitLightness Races in Orbit

290k51471802




290k51471802








  • 2





    possible duplicate: stackoverflow.com/questions/43827651/…

    – papagaga
    Nov 21 '18 at 15:26






  • 4





    Oddly works with gcc 8.2...

    – Matthieu Brucher
    Nov 21 '18 at 15:27






  • 8





    Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

    – Quentin
    Nov 21 '18 at 15:30






  • 6





    There's a defect report opened covering that case and it seem not restricted for std::cout

    – Jans
    Nov 21 '18 at 15:56








  • 3





    @Jans and that is worthy of an answer!

    – SergeyA
    Nov 21 '18 at 16:07














  • 2





    possible duplicate: stackoverflow.com/questions/43827651/…

    – papagaga
    Nov 21 '18 at 15:26






  • 4





    Oddly works with gcc 8.2...

    – Matthieu Brucher
    Nov 21 '18 at 15:27






  • 8





    Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

    – Quentin
    Nov 21 '18 at 15:30






  • 6





    There's a defect report opened covering that case and it seem not restricted for std::cout

    – Jans
    Nov 21 '18 at 15:56








  • 3





    @Jans and that is worthy of an answer!

    – SergeyA
    Nov 21 '18 at 16:07








2




2





possible duplicate: stackoverflow.com/questions/43827651/…

– papagaga
Nov 21 '18 at 15:26





possible duplicate: stackoverflow.com/questions/43827651/…

– papagaga
Nov 21 '18 at 15:26




4




4





Oddly works with gcc 8.2...

– Matthieu Brucher
Nov 21 '18 at 15:27





Oddly works with gcc 8.2...

– Matthieu Brucher
Nov 21 '18 at 15:27




8




8





Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

– Quentin
Nov 21 '18 at 15:30





Interesting. This looks like an optimization bug, where the compiler "sees through" the reference before ensuring that the reference itself is okay to use.

– Quentin
Nov 21 '18 at 15:30




6




6





There's a defect report opened covering that case and it seem not restricted for std::cout

– Jans
Nov 21 '18 at 15:56







There's a defect report opened covering that case and it seem not restricted for std::cout

– Jans
Nov 21 '18 at 15:56






3




3





@Jans and that is worthy of an answer!

– SergeyA
Nov 21 '18 at 16:07





@Jans and that is worthy of an answer!

– SergeyA
Nov 21 '18 at 16:07












1 Answer
1






active

oldest

votes


















22














There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.



For more reference, the backing defect report on the CWG is CWG-1472



EDIT:



Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code,
which is the result of applying the CWG defect mentioned above. The report was reopened because of
diagnosis location not because they were wrong about the acceptance






share|improve this answer





















  • 1





    That's the badger! Thanks Jans.

    – Lightness Races in Orbit
    Nov 21 '18 at 17:21








  • 1





    Are you implying that clang is wrong to accept the code?

    – Rakete1111
    Nov 22 '18 at 6:33






  • 1





    @Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

    – Jans
    Nov 22 '18 at 14:51













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',
autoActivateHeartbeat: false,
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%2f53415281%2flocal-reference-to-stdcout-captured-by-lambda-without-asking-for-it%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









22














There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.



For more reference, the backing defect report on the CWG is CWG-1472



EDIT:



Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code,
which is the result of applying the CWG defect mentioned above. The report was reopened because of
diagnosis location not because they were wrong about the acceptance






share|improve this answer





















  • 1





    That's the badger! Thanks Jans.

    – Lightness Races in Orbit
    Nov 21 '18 at 17:21








  • 1





    Are you implying that clang is wrong to accept the code?

    – Rakete1111
    Nov 22 '18 at 6:33






  • 1





    @Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

    – Jans
    Nov 22 '18 at 14:51


















22














There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.



For more reference, the backing defect report on the CWG is CWG-1472



EDIT:



Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code,
which is the result of applying the CWG defect mentioned above. The report was reopened because of
diagnosis location not because they were wrong about the acceptance






share|improve this answer





















  • 1





    That's the badger! Thanks Jans.

    – Lightness Races in Orbit
    Nov 21 '18 at 17:21








  • 1





    Are you implying that clang is wrong to accept the code?

    – Rakete1111
    Nov 22 '18 at 6:33






  • 1





    @Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

    – Jans
    Nov 22 '18 at 14:51
















22












22








22







There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.



For more reference, the backing defect report on the CWG is CWG-1472



EDIT:



Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code,
which is the result of applying the CWG defect mentioned above. The report was reopened because of
diagnosis location not because they were wrong about the acceptance






share|improve this answer















There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.



For more reference, the backing defect report on the CWG is CWG-1472



EDIT:



Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code,
which is the result of applying the CWG defect mentioned above. The report was reopened because of
diagnosis location not because they were wrong about the acceptance







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 28 '18 at 3:36

























answered Nov 21 '18 at 16:12









JansJans

8,96422635




8,96422635








  • 1





    That's the badger! Thanks Jans.

    – Lightness Races in Orbit
    Nov 21 '18 at 17:21








  • 1





    Are you implying that clang is wrong to accept the code?

    – Rakete1111
    Nov 22 '18 at 6:33






  • 1





    @Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

    – Jans
    Nov 22 '18 at 14:51
















  • 1





    That's the badger! Thanks Jans.

    – Lightness Races in Orbit
    Nov 21 '18 at 17:21








  • 1





    Are you implying that clang is wrong to accept the code?

    – Rakete1111
    Nov 22 '18 at 6:33






  • 1





    @Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

    – Jans
    Nov 22 '18 at 14:51










1




1





That's the badger! Thanks Jans.

– Lightness Races in Orbit
Nov 21 '18 at 17:21







That's the badger! Thanks Jans.

– Lightness Races in Orbit
Nov 21 '18 at 17:21






1




1





Are you implying that clang is wrong to accept the code?

– Rakete1111
Nov 22 '18 at 6:33





Are you implying that clang is wrong to accept the code?

– Rakete1111
Nov 22 '18 at 6:33




1




1





@Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

– Jans
Nov 22 '18 at 14:51







@Rakete1111 No, As Richard said in the report, when the reference variable is found to refer to constant expression, the referenced variable is used instead of the reference variable itself, the issue was reopened by diagnosis location not because they were wrong about the reference.

– Jans
Nov 22 '18 at 14:51






















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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415281%2flocal-reference-to-stdcout-captured-by-lambda-without-asking-for-it%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

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith