Local reference to std::cout captured by lambda without asking for it
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
|
show 13 more comments
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
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 forstd::cout
– Jans
Nov 21 '18 at 15:56
3
@Jans and that is worthy of an answer!
– SergeyA
Nov 21 '18 at 16:07
|
show 13 more comments
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
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
c++ lambda language-lawyer c++17
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 forstd::cout
– Jans
Nov 21 '18 at 15:56
3
@Jans and that is worthy of an answer!
– SergeyA
Nov 21 '18 at 16:07
|
show 13 more comments
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 forstd::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
|
show 13 more comments
1 Answer
1
active
oldest
votes
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
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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