I have some code which requires me to use *this
, but I want it to be noexcept friendly:
struct foo;
// Would actually be something with conditional noexcept
void do_something(foo&);
struct foo {
void fn()
noexcept(noexcept(::do_something(*this)))
{
::do_something(*this);
}
};
However, gcc rejects this:
<source>:7:43: error: invalid use of 'this' at top level
noexcept(noexcept(::do_something(*this)))
If I just access a member, gcc is fine:
void do_something(int);
struct bar {
int x;
void fn()
noexcept(noexcept(::do_something(x)))
{
::do_something(x);
}
};
However, if I access the member through the this
pointer, gcc complains again:
struct baz {
int x;
void fn()
noexcept(noexcept(::do_something(this->x)))
{
::do_something(this->x);
}
};
Diagnostic:
<source>:7:42: error: invalid use of 'this' at top level
noexcept(noexcept(::do_something(this->x)))
Every other compiler I tried accepts using this
inside the noexcept specification, but I don't actually know if it's gcc that has the bug or all the other compilers.
Can the keyword this
be used inside a noexcept specification?
The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.
Never. noexcept is for compiler performance optimizations in the same way that const is for compiler performance optimizations. That is, almost never. noexcept is primarily used to allow "you" to detect at compile-time if a function can throw an exception.
The dynamic exception specification, or throw(optional_type_list) specification, was deprecated in C++11 and removed in C++17, except for throw() , which is an alias for noexcept(true) . We recommended you apply noexcept to any function that never allows an exception to propagate up the call stack.
When an exception is thrown from a function that is declared noexcept or noexcept(true) , std::terminate is invoked. When an exception is thrown from a function declared as throw() in /std:c++14 mode, the result is undefined behavior. No specific function is invoked.
Yes, it is allowed. [expr.prim.this]p2 says:
If a declaration declares a member function or member function template of a class
X
, the expressionthis
is a prvalue of type “pointer to cv-qualifier-seqX
” between the optional cv-qualifier-seq and the end of the function-definition, [...].
The cv-qualifier-seq refers to the cv qualifiers of the member function, which appear before the noexcept specifier:
parameters-and-qualifiers: ( parameter-declaration-clause ) cv-qualifier-seq[opt] ref-qualifier[opt] noexcept-specifier[opt] attribute-specifier-seq[opt]
So, this
is a valid expression to use in the noexcept-specifier. This was a DR (cwg1207), which gcc doesn't implement. The bug report.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With