Why are std::begin and std::end “not memory safe”?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
In this blog post, Eric Niebler states that:
What is wrong with std::begin and std::end? Surprise! they are not
memory safe. Consider what this code does:
extern std::vector<int> get_data();
auto it = std::begin(get_data());
int i = *it; // BOOM
std::begin has two overloads for const and non-const lvalues. Trouble
is, rvalues bind to const lvalue references, leading to the dangling
iterator it above.
I'm having trouble understanding his point and why it is a dangling reference.
Could someone explain?
c++ c++11 iterator std
|
show 1 more comment
In this blog post, Eric Niebler states that:
What is wrong with std::begin and std::end? Surprise! they are not
memory safe. Consider what this code does:
extern std::vector<int> get_data();
auto it = std::begin(get_data());
int i = *it; // BOOM
std::begin has two overloads for const and non-const lvalues. Trouble
is, rvalues bind to const lvalue references, leading to the dangling
iterator it above.
I'm having trouble understanding his point and why it is a dangling reference.
Could someone explain?
c++ c++11 iterator std
17
How is the above code any different fromauto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?
– john
Feb 11 at 7:56
10
@john Eric is saying thatranges::beginis better thanstd::begin, he isn't claiming anything about.begin.
– Marc Glisse
Feb 11 at 8:58
3
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
2
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates thatstd::begin()is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.
– Justin Time
Feb 12 at 7:40
|
show 1 more comment
In this blog post, Eric Niebler states that:
What is wrong with std::begin and std::end? Surprise! they are not
memory safe. Consider what this code does:
extern std::vector<int> get_data();
auto it = std::begin(get_data());
int i = *it; // BOOM
std::begin has two overloads for const and non-const lvalues. Trouble
is, rvalues bind to const lvalue references, leading to the dangling
iterator it above.
I'm having trouble understanding his point and why it is a dangling reference.
Could someone explain?
c++ c++11 iterator std
In this blog post, Eric Niebler states that:
What is wrong with std::begin and std::end? Surprise! they are not
memory safe. Consider what this code does:
extern std::vector<int> get_data();
auto it = std::begin(get_data());
int i = *it; // BOOM
std::begin has two overloads for const and non-const lvalues. Trouble
is, rvalues bind to const lvalue references, leading to the dangling
iterator it above.
I'm having trouble understanding his point and why it is a dangling reference.
Could someone explain?
c++ c++11 iterator std
c++ c++11 iterator std
edited Feb 11 at 17:51
Cody Gray♦
196k35385475
196k35385475
asked Feb 11 at 7:33
DavidbrczDavidbrcz
1,5681119
1,5681119
17
How is the above code any different fromauto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?
– john
Feb 11 at 7:56
10
@john Eric is saying thatranges::beginis better thanstd::begin, he isn't claiming anything about.begin.
– Marc Glisse
Feb 11 at 8:58
3
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
2
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates thatstd::begin()is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.
– Justin Time
Feb 12 at 7:40
|
show 1 more comment
17
How is the above code any different fromauto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?
– john
Feb 11 at 7:56
10
@john Eric is saying thatranges::beginis better thanstd::begin, he isn't claiming anything about.begin.
– Marc Glisse
Feb 11 at 8:58
3
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
2
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates thatstd::begin()is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.
– Justin Time
Feb 12 at 7:40
17
17
How is the above code any different from
auto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?– john
Feb 11 at 7:56
How is the above code any different from
auto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?– john
Feb 11 at 7:56
10
10
@john Eric is saying that
ranges::begin is better than std::begin, he isn't claiming anything about .begin.– Marc Glisse
Feb 11 at 8:58
@john Eric is saying that
ranges::begin is better than std::begin, he isn't claiming anything about .begin.– Marc Glisse
Feb 11 at 8:58
3
3
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
2
2
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates that
std::begin() is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.– Justin Time
Feb 12 at 7:40
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates that
std::begin() is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.– Justin Time
Feb 12 at 7:40
|
show 1 more comment
6 Answers
6
active
oldest
votes
The get_data function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
Becausestd::beginlets you make that mistake, butstd::ranges::beginwill not.
– Eric Niebler
Feb 11 at 16:17
add a comment |
I think Eric's point about std::begin is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason whystd::beginaccepts r-values is to letbegin(c)andc.begin()be perfectly equivalent. (but yes obviously this overload set would be ideal)
– YSC
Feb 11 at 12:24
3
@YSC.begin()could also be made to reject rvalues, couldn't it?iterator begin() && = delete;
– The Vee
Feb 11 at 18:00
|
show 4 more comments
The temporary vector returned by get_data goes out of scope after std::begin is done. It is not kept alive, so it is an iterator into a destroyed object.
add a comment |
Is it fair to say this is a memory safety failing of std::begin?
There is no 'safe' way of creating an iterator such that it will be valid to follow the pointer after the container is deleted.
It lacks a check that another method has, but it's not like there is no way to make a ranges derived iterator go pop. You just have to try a bit harder...
add a comment |
Because it allows initialisation from an rvalue, which is bad.
add a comment |
in fact , the complicated function can be simplified to two short functions , such as
int& foo(int x){
return x;
}
int generate_a_int(){
return 42;
}
and then invoke it foo(generate_a_int()), a temporary value is generated , once out of the function body, the temporary value generated by generate_a_int() is destroy , and then dangle reference is happened ...
do you understand now?
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%2f54625792%2fwhy-are-stdbegin-and-stdend-not-memory-safe%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
The get_data function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
Becausestd::beginlets you make that mistake, butstd::ranges::beginwill not.
– Eric Niebler
Feb 11 at 16:17
add a comment |
The get_data function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
Becausestd::beginlets you make that mistake, butstd::ranges::beginwill not.
– Eric Niebler
Feb 11 at 16:17
add a comment |
The get_data function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
The get_data function returns an object. When used the way shown, that object will be a temporary object, which will be destructed once the full expression ends. The iterator now references a vector object which no longer exists, and can't be dereferenced or used in any useful way.
answered Feb 11 at 7:37
Some programmer dudeSome programmer dude
305k25265427
305k25265427
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
Becausestd::beginlets you make that mistake, butstd::ranges::beginwill not.
– Eric Niebler
Feb 11 at 16:17
add a comment |
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
Becausestd::beginlets you make that mistake, butstd::ranges::beginwill not.
– Eric Niebler
Feb 11 at 16:17
16
16
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
Though this is definitely correct, isn't john's comment to the original post also appropriate? How does the given example show a problem of std::begin and std::end?
– Benjamin Bihler
Feb 11 at 8:35
18
18
Because
std::begin lets you make that mistake, but std::ranges::begin will not.– Eric Niebler
Feb 11 at 16:17
Because
std::begin lets you make that mistake, but std::ranges::begin will not.– Eric Niebler
Feb 11 at 16:17
add a comment |
I think Eric's point about std::begin is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason whystd::beginaccepts r-values is to letbegin(c)andc.begin()be perfectly equivalent. (but yes obviously this overload set would be ideal)
– YSC
Feb 11 at 12:24
3
@YSC.begin()could also be made to reject rvalues, couldn't it?iterator begin() && = delete;
– The Vee
Feb 11 at 18:00
|
show 4 more comments
I think Eric's point about std::begin is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason whystd::beginaccepts r-values is to letbegin(c)andc.begin()be perfectly equivalent. (but yes obviously this overload set would be ideal)
– YSC
Feb 11 at 12:24
3
@YSC.begin()could also be made to reject rvalues, couldn't it?iterator begin() && = delete;
– The Vee
Feb 11 at 18:00
|
show 4 more comments
I think Eric's point about std::begin is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
I think Eric's point about std::begin is that it silently accepts an rvalue container as an argument to begin with. On the face of it, the problem with the code is also exemplified in
auto it = get_data().begin();
But std::begin is a free function template, it can be made to reject rvalues without needing to add the proper reference qualifiers to each container's begin members. By "just" forwarding it misses an opportunity to add a layer of memory safety to code.
Ideally, the overload set could have benefited from the addition of
template< class C >
void begin( C&& ) = delete;
That one would have caused the code in the blog post to be flat out rejected on the spot.
edited Feb 12 at 6:42
answered Feb 11 at 8:47
StoryTellerStoryTeller
105k13221285
105k13221285
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason whystd::beginaccepts r-values is to letbegin(c)andc.begin()be perfectly equivalent. (but yes obviously this overload set would be ideal)
– YSC
Feb 11 at 12:24
3
@YSC.begin()could also be made to reject rvalues, couldn't it?iterator begin() && = delete;
– The Vee
Feb 11 at 18:00
|
show 4 more comments
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason whystd::beginaccepts r-values is to letbegin(c)andc.begin()be perfectly equivalent. (but yes obviously this overload set would be ideal)
– YSC
Feb 11 at 12:24
3
@YSC.begin()could also be made to reject rvalues, couldn't it?iterator begin() && = delete;
– The Vee
Feb 11 at 18:00
1
1
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
Is it possible for us to make a warning of deprecation or usage for that particular template instantiation instead of outright deleting it? Compiler specific extensions allowed.
– Paul Stelian
Feb 11 at 9:51
4
4
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
@PaulStelian - Here's how btw, pure C++14. coliru.stacked-crooked.com/a/7c99059b5b1a8dca
– StoryTeller
Feb 11 at 10:01
3
3
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
@PaulStelian - No, we can't. I intentionally provided an example in another namespace. To add this overload, we'd need to write a proposal, then get it voted int o the standard.
– StoryTeller
Feb 11 at 11:25
3
3
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason why
std::begin accepts r-values is to let begin(c) and c.begin() be perfectly equivalent. (but yes obviously this overload set would be ideal)– YSC
Feb 11 at 12:24
The thing is, as Alexandrescu points it out with humour in its 2018 cppcon talk, the C++ committee likes to be consistent in its past errors. One might think the reason why
std::begin accepts r-values is to let begin(c) and c.begin() be perfectly equivalent. (but yes obviously this overload set would be ideal)– YSC
Feb 11 at 12:24
3
3
@YSC
.begin() could also be made to reject rvalues, couldn't it? iterator begin() && = delete;– The Vee
Feb 11 at 18:00
@YSC
.begin() could also be made to reject rvalues, couldn't it? iterator begin() && = delete;– The Vee
Feb 11 at 18:00
|
show 4 more comments
The temporary vector returned by get_data goes out of scope after std::begin is done. It is not kept alive, so it is an iterator into a destroyed object.
add a comment |
The temporary vector returned by get_data goes out of scope after std::begin is done. It is not kept alive, so it is an iterator into a destroyed object.
add a comment |
The temporary vector returned by get_data goes out of scope after std::begin is done. It is not kept alive, so it is an iterator into a destroyed object.
The temporary vector returned by get_data goes out of scope after std::begin is done. It is not kept alive, so it is an iterator into a destroyed object.
answered Feb 11 at 7:38
Jesper JuhlJesper Juhl
17.6k32647
17.6k32647
add a comment |
add a comment |
Is it fair to say this is a memory safety failing of std::begin?
There is no 'safe' way of creating an iterator such that it will be valid to follow the pointer after the container is deleted.
It lacks a check that another method has, but it's not like there is no way to make a ranges derived iterator go pop. You just have to try a bit harder...
add a comment |
Is it fair to say this is a memory safety failing of std::begin?
There is no 'safe' way of creating an iterator such that it will be valid to follow the pointer after the container is deleted.
It lacks a check that another method has, but it's not like there is no way to make a ranges derived iterator go pop. You just have to try a bit harder...
add a comment |
Is it fair to say this is a memory safety failing of std::begin?
There is no 'safe' way of creating an iterator such that it will be valid to follow the pointer after the container is deleted.
It lacks a check that another method has, but it's not like there is no way to make a ranges derived iterator go pop. You just have to try a bit harder...
Is it fair to say this is a memory safety failing of std::begin?
There is no 'safe' way of creating an iterator such that it will be valid to follow the pointer after the container is deleted.
It lacks a check that another method has, but it's not like there is no way to make a ranges derived iterator go pop. You just have to try a bit harder...
answered Feb 12 at 0:37
drjpizzledrjpizzle
19113
19113
add a comment |
add a comment |
Because it allows initialisation from an rvalue, which is bad.
add a comment |
Because it allows initialisation from an rvalue, which is bad.
add a comment |
Because it allows initialisation from an rvalue, which is bad.
Because it allows initialisation from an rvalue, which is bad.
answered Feb 12 at 13:39
ANoneANone
1604
1604
add a comment |
add a comment |
in fact , the complicated function can be simplified to two short functions , such as
int& foo(int x){
return x;
}
int generate_a_int(){
return 42;
}
and then invoke it foo(generate_a_int()), a temporary value is generated , once out of the function body, the temporary value generated by generate_a_int() is destroy , and then dangle reference is happened ...
do you understand now?
add a comment |
in fact , the complicated function can be simplified to two short functions , such as
int& foo(int x){
return x;
}
int generate_a_int(){
return 42;
}
and then invoke it foo(generate_a_int()), a temporary value is generated , once out of the function body, the temporary value generated by generate_a_int() is destroy , and then dangle reference is happened ...
do you understand now?
add a comment |
in fact , the complicated function can be simplified to two short functions , such as
int& foo(int x){
return x;
}
int generate_a_int(){
return 42;
}
and then invoke it foo(generate_a_int()), a temporary value is generated , once out of the function body, the temporary value generated by generate_a_int() is destroy , and then dangle reference is happened ...
do you understand now?
in fact , the complicated function can be simplified to two short functions , such as
int& foo(int x){
return x;
}
int generate_a_int(){
return 42;
}
and then invoke it foo(generate_a_int()), a temporary value is generated , once out of the function body, the temporary value generated by generate_a_int() is destroy , and then dangle reference is happened ...
do you understand now?
answered Feb 14 at 9:37
lisuwanglisuwang
223
223
add a comment |
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%2f54625792%2fwhy-are-stdbegin-and-stdend-not-memory-safe%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
17
How is the above code any different from
auto it = get_data().begin();. That code has the same problem I think, so what point is the author is making?– john
Feb 11 at 7:56
10
@john Eric is saying that
ranges::beginis better thanstd::begin, he isn't claiming anything about.begin.– Marc Glisse
Feb 11 at 8:58
3
@MarcGlisse OK, I was misled by the title of this post, and I couldn't easily find the original quote.
– john
Feb 11 at 9:00
Related question: stackoverflow.com/questions/48976859/…
– Arne Vogel
Feb 11 at 12:26
2
Personally, I would say that's more a combination of "not Machiavelli-safe" or "not derp-safe" and a quirk of rvalue references than "not memory-safe", since it demonstrates that
std::begin()is exactly as memory-safe as the parameter you pass to it, and not inherently unsafe solely in and of itself. That's just me, though.– Justin Time
Feb 12 at 7:40