Access elements in std::string where positon of string is greater than its size
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
In case of std::string, if we access an element where (element position) > (size of string)
the standard says that it returns a reference to an object of type charT
with value charT()
.
const_reference operator(size_type pos) const;
reference operator(size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
http://eel.is/c++draft/strings#string.access-1
Unfortunately I couldn't reason about this, it would have been better if it has been Undefined Behavior.
Can somebody explain the rationale behind this?
c++ string c++11 language-lawyer
|
show 12 more comments
In case of std::string, if we access an element where (element position) > (size of string)
the standard says that it returns a reference to an object of type charT
with value charT()
.
const_reference operator(size_type pos) const;
reference operator(size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
http://eel.is/c++draft/strings#string.access-1
Unfortunately I couldn't reason about this, it would have been better if it has been Undefined Behavior.
Can somebody explain the rationale behind this?
c++ string c++11 language-lawyer
1
@Yola you mean becauseoperator
has to check if the index is< size
in any case?
– user463035818
8 hours ago
4
@user463035818 no that's not true. Subscript operator does not perform a check.string::at()
does and for that reason it throws
– KostasRim
8 hours ago
4
Doesn't violating "Expects:pos <= size()
" lead to UB straight away? The "Otherwise" refers only to thepos == size
case, no?
– Max Langhof
8 hours ago
5
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
5
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago
|
show 12 more comments
In case of std::string, if we access an element where (element position) > (size of string)
the standard says that it returns a reference to an object of type charT
with value charT()
.
const_reference operator(size_type pos) const;
reference operator(size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
http://eel.is/c++draft/strings#string.access-1
Unfortunately I couldn't reason about this, it would have been better if it has been Undefined Behavior.
Can somebody explain the rationale behind this?
c++ string c++11 language-lawyer
In case of std::string, if we access an element where (element position) > (size of string)
the standard says that it returns a reference to an object of type charT
with value charT()
.
const_reference operator(size_type pos) const;
reference operator(size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
http://eel.is/c++draft/strings#string.access-1
Unfortunately I couldn't reason about this, it would have been better if it has been Undefined Behavior.
Can somebody explain the rationale behind this?
c++ string c++11 language-lawyer
c++ string c++11 language-lawyer
edited 8 hours ago
Samer Tufail
1,628922
1,628922
asked 9 hours ago
AImx1AImx1
455217
455217
1
@Yola you mean becauseoperator
has to check if the index is< size
in any case?
– user463035818
8 hours ago
4
@user463035818 no that's not true. Subscript operator does not perform a check.string::at()
does and for that reason it throws
– KostasRim
8 hours ago
4
Doesn't violating "Expects:pos <= size()
" lead to UB straight away? The "Otherwise" refers only to thepos == size
case, no?
– Max Langhof
8 hours ago
5
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
5
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago
|
show 12 more comments
1
@Yola you mean becauseoperator
has to check if the index is< size
in any case?
– user463035818
8 hours ago
4
@user463035818 no that's not true. Subscript operator does not perform a check.string::at()
does and for that reason it throws
– KostasRim
8 hours ago
4
Doesn't violating "Expects:pos <= size()
" lead to UB straight away? The "Otherwise" refers only to thepos == size
case, no?
– Max Langhof
8 hours ago
5
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
5
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago
1
1
@Yola you mean because
operator
has to check if the index is < size
in any case?– user463035818
8 hours ago
@Yola you mean because
operator
has to check if the index is < size
in any case?– user463035818
8 hours ago
4
4
@user463035818 no that's not true. Subscript operator does not perform a check.
string::at()
does and for that reason it throws– KostasRim
8 hours ago
@user463035818 no that's not true. Subscript operator does not perform a check.
string::at()
does and for that reason it throws– KostasRim
8 hours ago
4
4
Doesn't violating "Expects:
pos <= size()
" lead to UB straight away? The "Otherwise" refers only to the pos == size
case, no?– Max Langhof
8 hours ago
Doesn't violating "Expects:
pos <= size()
" lead to UB straight away? The "Otherwise" refers only to the pos == size
case, no?– Max Langhof
8 hours ago
5
5
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
5
5
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago
|
show 12 more comments
4 Answers
4
active
oldest
votes
You have to consider the full specs.
First of all:
Expects: pos <= size().
If you dont follow the precondition you have undefined behaviour anyhow. Now...
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
The only (valid) case that "otherwise" refers to is when pos == size()
. And that is probably to emulate c string behaviour that have a some_string[size]
element that can be accessed. Note that charT()
is typically just ''
.
PS: One might think that to implement the specification, operator
would have to check if pos == size
. However, if the underlying character array has a charT()
at the end of the string, then you get the described behaviour basically for free. Hence, what seems a little different from "usual" access into an array is actually just that.
add a comment |
Statement 1 is the precondition for statement 2:
Expects:
pos <= size()
.
Returns:
*(begin() + pos) if pos < size()
.
Otherwise (so here the only viable possibility is
pos == size()
), returns a reference to an object of typecharT
with valuecharT()
(i.e.''
), where modifying the object to any value other thancharT()
leads to undefined behavior.
str[str.size()]
basically points to the null-terminator character. You can read and write it, but you may only write a null into it.
add a comment |
The operator expects pos
to be less than or equal to size()
, so if it is not less, then it is expected to be equal.
add a comment |
Additionally to the previous answers please take a look at the libcxx
(the llvm implementation) defines std::string::operator
like:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
Take a look at the .at()
that properly throws instead.
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
As you can, in the first case, there is a runtime assert(thanks t.niese for pointing out) which is triggered only in debug mode whereas the second will always throw, regardless of the build options of the library.
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?
– AImx1
8 hours ago
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
@AImx1 because the standard says thatname[100]
is undefined behavior, and not that it must throw._LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode
– t.niese
8 hours ago
|
show 2 more comments
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%2f55588104%2faccess-elements-in-stdstring-where-positon-of-string-is-greater-than-its-size%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You have to consider the full specs.
First of all:
Expects: pos <= size().
If you dont follow the precondition you have undefined behaviour anyhow. Now...
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
The only (valid) case that "otherwise" refers to is when pos == size()
. And that is probably to emulate c string behaviour that have a some_string[size]
element that can be accessed. Note that charT()
is typically just ''
.
PS: One might think that to implement the specification, operator
would have to check if pos == size
. However, if the underlying character array has a charT()
at the end of the string, then you get the described behaviour basically for free. Hence, what seems a little different from "usual" access into an array is actually just that.
add a comment |
You have to consider the full specs.
First of all:
Expects: pos <= size().
If you dont follow the precondition you have undefined behaviour anyhow. Now...
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
The only (valid) case that "otherwise" refers to is when pos == size()
. And that is probably to emulate c string behaviour that have a some_string[size]
element that can be accessed. Note that charT()
is typically just ''
.
PS: One might think that to implement the specification, operator
would have to check if pos == size
. However, if the underlying character array has a charT()
at the end of the string, then you get the described behaviour basically for free. Hence, what seems a little different from "usual" access into an array is actually just that.
add a comment |
You have to consider the full specs.
First of all:
Expects: pos <= size().
If you dont follow the precondition you have undefined behaviour anyhow. Now...
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
The only (valid) case that "otherwise" refers to is when pos == size()
. And that is probably to emulate c string behaviour that have a some_string[size]
element that can be accessed. Note that charT()
is typically just ''
.
PS: One might think that to implement the specification, operator
would have to check if pos == size
. However, if the underlying character array has a charT()
at the end of the string, then you get the described behaviour basically for free. Hence, what seems a little different from "usual" access into an array is actually just that.
You have to consider the full specs.
First of all:
Expects: pos <= size().
If you dont follow the precondition you have undefined behaviour anyhow. Now...
Returns: *(begin() + pos) if pos < size(). Otherwise, returns a
reference to an object of type charT with value charT(), where
modifying the object to any value other than charT() leads to
undefined behavior.
The only (valid) case that "otherwise" refers to is when pos == size()
. And that is probably to emulate c string behaviour that have a some_string[size]
element that can be accessed. Note that charT()
is typically just ''
.
PS: One might think that to implement the specification, operator
would have to check if pos == size
. However, if the underlying character array has a charT()
at the end of the string, then you get the described behaviour basically for free. Hence, what seems a little different from "usual" access into an array is actually just that.
edited 8 hours ago
answered 8 hours ago
user463035818user463035818
18.7k42870
18.7k42870
add a comment |
add a comment |
Statement 1 is the precondition for statement 2:
Expects:
pos <= size()
.
Returns:
*(begin() + pos) if pos < size()
.
Otherwise (so here the only viable possibility is
pos == size()
), returns a reference to an object of typecharT
with valuecharT()
(i.e.''
), where modifying the object to any value other thancharT()
leads to undefined behavior.
str[str.size()]
basically points to the null-terminator character. You can read and write it, but you may only write a null into it.
add a comment |
Statement 1 is the precondition for statement 2:
Expects:
pos <= size()
.
Returns:
*(begin() + pos) if pos < size()
.
Otherwise (so here the only viable possibility is
pos == size()
), returns a reference to an object of typecharT
with valuecharT()
(i.e.''
), where modifying the object to any value other thancharT()
leads to undefined behavior.
str[str.size()]
basically points to the null-terminator character. You can read and write it, but you may only write a null into it.
add a comment |
Statement 1 is the precondition for statement 2:
Expects:
pos <= size()
.
Returns:
*(begin() + pos) if pos < size()
.
Otherwise (so here the only viable possibility is
pos == size()
), returns a reference to an object of typecharT
with valuecharT()
(i.e.''
), where modifying the object to any value other thancharT()
leads to undefined behavior.
str[str.size()]
basically points to the null-terminator character. You can read and write it, but you may only write a null into it.
Statement 1 is the precondition for statement 2:
Expects:
pos <= size()
.
Returns:
*(begin() + pos) if pos < size()
.
Otherwise (so here the only viable possibility is
pos == size()
), returns a reference to an object of typecharT
with valuecharT()
(i.e.''
), where modifying the object to any value other thancharT()
leads to undefined behavior.
str[str.size()]
basically points to the null-terminator character. You can read and write it, but you may only write a null into it.
answered 8 hours ago
rustyxrustyx
33.2k8100144
33.2k8100144
add a comment |
add a comment |
The operator expects pos
to be less than or equal to size()
, so if it is not less, then it is expected to be equal.
add a comment |
The operator expects pos
to be less than or equal to size()
, so if it is not less, then it is expected to be equal.
add a comment |
The operator expects pos
to be less than or equal to size()
, so if it is not less, then it is expected to be equal.
The operator expects pos
to be less than or equal to size()
, so if it is not less, then it is expected to be equal.
edited 7 hours ago
Raimund Krämer
710425
710425
answered 8 hours ago
YolaYola
11.4k64773
11.4k64773
add a comment |
add a comment |
Additionally to the previous answers please take a look at the libcxx
(the llvm implementation) defines std::string::operator
like:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
Take a look at the .at()
that properly throws instead.
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
As you can, in the first case, there is a runtime assert(thanks t.niese for pointing out) which is triggered only in debug mode whereas the second will always throw, regardless of the build options of the library.
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?
– AImx1
8 hours ago
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
@AImx1 because the standard says thatname[100]
is undefined behavior, and not that it must throw._LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode
– t.niese
8 hours ago
|
show 2 more comments
Additionally to the previous answers please take a look at the libcxx
(the llvm implementation) defines std::string::operator
like:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
Take a look at the .at()
that properly throws instead.
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
As you can, in the first case, there is a runtime assert(thanks t.niese for pointing out) which is triggered only in debug mode whereas the second will always throw, regardless of the build options of the library.
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?
– AImx1
8 hours ago
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
@AImx1 because the standard says thatname[100]
is undefined behavior, and not that it must throw._LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode
– t.niese
8 hours ago
|
show 2 more comments
Additionally to the previous answers please take a look at the libcxx
(the llvm implementation) defines std::string::operator
like:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
Take a look at the .at()
that properly throws instead.
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
As you can, in the first case, there is a runtime assert(thanks t.niese for pointing out) which is triggered only in debug mode whereas the second will always throw, regardless of the build options of the library.
Additionally to the previous answers please take a look at the libcxx
(the llvm implementation) defines std::string::operator
like:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator(size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
Take a look at the .at()
that properly throws instead.
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
As you can, in the first case, there is a runtime assert(thanks t.niese for pointing out) which is triggered only in debug mode whereas the second will always throw, regardless of the build options of the library.
edited 8 hours ago
answered 8 hours ago
KostasRimKostasRim
1,5701926
1,5701926
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?
– AImx1
8 hours ago
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
@AImx1 because the standard says thatname[100]
is undefined behavior, and not that it must throw._LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode
– t.niese
8 hours ago
|
show 2 more comments
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?
– AImx1
8 hours ago
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
@AImx1 because the standard says thatname[100]
is undefined behavior, and not that it must throw._LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode
– t.niese
8 hours ago
2
2
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
That's not a static assert it is a runtime assert. A static_assert is something that is check at compile time, and a static assert is done for both release and debug builds.
– t.niese
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
Wow thanks for catching that up! You are absolutely right ;) made an edit!
– KostasRim
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?– AImx1
8 hours ago
std::string name = "StackOverflow";
std::cout << name[100];
@t.niese If it a run time assert, why does the below code doesn't crash?– AImx1
8 hours ago
1
1
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
@AImx1 cause you didn't specify that you want the debug build when building the library?
– KostasRim
8 hours ago
2
2
@AImx1 because the standard says that
name[100]
is undefined behavior, and not that it must throw. _LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode– t.niese
8 hours ago
@AImx1 because the standard says that
name[100]
is undefined behavior, and not that it must throw. _LIBCPP_ASSERT
is a debugging assert that has to be explicitly enabled and is not automatically enable for regular debug builds, and it is run-time dependent llvm: DebugMode– t.niese
8 hours ago
|
show 2 more comments
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%2f55588104%2faccess-elements-in-stdstring-where-positon-of-string-is-greater-than-its-size%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
1
@Yola you mean because
operator
has to check if the index is< size
in any case?– user463035818
8 hours ago
4
@user463035818 no that's not true. Subscript operator does not perform a check.
string::at()
does and for that reason it throws– KostasRim
8 hours ago
4
Doesn't violating "Expects:
pos <= size()
" lead to UB straight away? The "Otherwise" refers only to thepos == size
case, no?– Max Langhof
8 hours ago
5
exactly I think the crux is "Expects: pos <= size()." if you dont follow the precondition you are in UB land anyhow, so it is just about accesing the "end" of the string
– user463035818
8 hours ago
5
@AImx1 Where does the standard say that violating an "Expects" clause is anything other than UB?
– Max Langhof
8 hours ago