I'm trying to compile the following code with clang++ -std=c++11 -c and it fails:
void g() noexcept {}
template <typename Func>
void f(Func && func) noexcept(noexcept(func()))
{ static_assert(noexcept(func()), "func()"); } // No error!
void h() { f(&g); } // No error!
static_assert(noexcept(f(&g)), "Error!");
The error message Clang 3.4.2 gives me is:
test.h:9:1: error: static_assert failed "Error!"
static_assert(noexcept(f(&g)), "Error!");
^ ~~~~~~~~~~~~~~~
What am I missing here?
noexcept is not a part of a function type.
Thus, &g is just your run of the mill expression of type void(*)(), with no special noexcept powers. So is g, as it decays to the function pointer. When such a function pointer is eventually called, it has no noexcept specification, and thus the entire expression is not noexcept.
Related
Consider the following code:
class Base {
public:
#ifdef __VIRTUAL__
virtual ~Base() {}
#else
~Base() {}
#endif
};
class Derived : public Base {
public:
~Derived() {}
private:
static void operator delete(void*) = delete;
};
int main() {
Derived d;
}
It'll compiled successfully with cmd
g++ -std=c++11 main.cpp
but failed with cmd
g++ -std=c++11 -D__VIRTUAL__ main.cpp
The output shows the operator delete is required
main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
~Derived() {}
^
main.cpp:14:17: error: declared here
static void operator delete(void*) = delete;
^
main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
~Derived() {}
^
main.cpp:14:17: error: declared here
static void operator delete(void*) = delete;
^
It means that if I use virtual destructor function, I cannnot delete operator delete .
Why is this happened, why virtual destructor required global operator delete even if created on stack.
The operator delete function is only called during deletion of an object with dynamic storage duration. It's not called by your program.
However, the standard requires that this function be available if there is a virtual destructor, even if the object is never actually used dynamically.
In the C++17 standard this is [class.dtor]/13:
At the point of definition of a virtual destructor (including an implicit definition), the non-array deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor of the destructor’s class. If the lookup fails or if the deallocation function has a deleted definition, the program is ill-formed. [Note: This assures that a deallocation function corresponding to the dynamic type of an object is available for the delete-expression. —end note ]
Why does the standard require this? I have no idea but you're going to have to find some other approach to solve your problem. Maybe this thread will be useful: Any way to prevent dynamic allocation of a class?
I am unable to understand the use & purpose of the noexcept keyword in C++11/14. I understand that it is a signature for a function that does not emit exceptions. But does it really work?
Look at this code below :
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void seev (vector<int> &v) noexcept;
void seev (vector<int> &v) noexcept
{
for (int i=0;i<10;++i)
{
cout<<v.at(i)<<' ';
}
}
int main()
{
vector<int> v {1,2,3,4,5};
seev(v);
return 0;
}
The above code will surely throw an out_of_range exception. So the use of noexcept here is useless, or is it?
My queries are :
How does noexcept work?
How is it used?
What throw() wasn't able to do that noexcept could?
A noexcept specification on a function is merely a method for a programmer to inform the compiler whether or not a function should throw exceptions.
The compiler can use this information to enable certain optimizations on non-throwing functions as well as enable the noexcept operator, which can check at compile time if a particular expression is declared to throw any exceptions.
For example, containers such as std::vector will move their elements if the elements' move constructor is noexcept, and copy otherwise (unless the copy constructor is not accessible, but a potentially throwing move constructor is, in which case the strong exception guarantee is waived).
noexcept is an improved version of throw(), which is deprecated in C++11. Unlike throw(), noexcept will not call std::unexpected and may or may not unwind the stack, which potentially allows the compiler to implement noexcept without the runtime overhead of throw().
For more details, please visit below websites
https://akrzemi1.wordpress.com/2014/04/24/noexcept-what-for/
When should I really use noexcept?
Edit: Sample source code to illustrate above points.
// whether foo is declared noexcept depends on if the expression
// T() will throw any exceptions, check in compile time
template <class T>
void foo() noexcept(noexcept(T())) {
}
void bar() noexcept(true) {
}
void baz() noexcept {
throw 42;
} // noexcept is the same as noexcept(true)
int main()
{
foo<int>(); // noexcept(noexcept(int())) => noexcept(true), so this is fine
bar(); // fine
baz(); // compiles, but at runtime this calls std::terminate
}
I'm posting 2 pieces of code to explain your problem:
Code 1:
#include <iostream>
using namespace std;
void foo() noexcept // see the noexcept specifier
{
throw 42;
}
int main()
{
try
{
foo();
}
catch(...)
{
cerr<<"exception caught\n";
}
return 0;
}
Here the output will be :-
terminate called after throwing an instance of 'int'
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
If I remove the noexceptthen:
Code 2:
#include <iostream>
using namespace std;
void foo() // noexcept is eliminated
{
throw 42;
}
int main()
{
try
{
foo();
}
catch(...)
{
cerr<<"exception caught\n";
}
return 0;
}
Output will be :-
exception caught
Because foo was signed as noexcept, hence terminate was called.
Inheriting constructors and the implicitly-declared default constructors, copy constructors, move constructors, destructors, copy-assignment operators, and move-assignment operators are all noexcept(true) by default, unless they are required to call a function that is noexcept(false), in which case these functions are noexcept(false).
You can also write lines like:
cout << boolalpha << noexcept(foo); // here noexcept acts as
// an operator instead of a specifier
The above line will check if foo will throw an exception or not. If it would throw then the return value will be true else false.
You can read more about these in this: http://scottmeyers.blogspot.dk/2014/03/declare-functions-noexcept-whenever.html
noexcept indicates that a function is intended not to to throw an exception, a guarantee you as a developer provides, that is not enforced by the compiler. So using it in a situation where your function calls functions that might throw exceptions that you do not catch yourself is bad.
The whole range of throw() specifiers were removed because the exception specifiers were less than optimal in C++, see: Difference between C++03 throw() specifier C++11 noexcept
noexcept has the advantage of not stating which exception is thrown, but rather whether an exception is thrown or not. It accepts a parameter which may be false if you expect the function to throw an exception.
The uses of this, can be in for instance an inherited class structure, where one super class wish to "enforce" to an inherited class, that a specific virtual function is not allowed to throw an exception. Further more the compiler may use the information for optimization.
noexcept is also an operator which can evaluate an expression and return whether or not that expression may thrown an exception or not, as per § 5.3.7.
5.3.7 noexcept operator [expr.unary.noexcept]
1 The noexcept operator determines whether the evaluation of its operand, which is an unevaluated operand
(Clause 5), can throw an exception (15.1).
noexcept-expression:
noexcept ( expression )
2 The result of the noexcept operator is a constant of type bool and is an rvalue.
3 The result of the noexcept operator is false if in a potentially-evaluated context the expression would
contain
— a potentially-evaluated call to a function, member function, function pointer, or member function pointer that does not have a non-throwing exception-specification (15.4), unless the call is a constant
expression (5.19),
— a potentially-evaluated throw-expression (15.1),
— a potentially-evaluated dynamic_cast expression dynamic_cast(v), where T is a reference type, that requires a run-time check (5.2.7), or
— a potentially-evaluated typeid expression (5.2.8) applied to a glvalue expression whose type is a polymorphic class type (10.3).
Otherwise, the result is true.
I can't explain the possible optimizations as well as Scott Meyers: http://aristeia.com/EC++11-14/noexcept%202014-03-31.pdf from his blog post: Declare functions noexcept whenever possible?
The difference between unwinding the call stack and possibly unwinding it has a surprisingly large impact on code generation. In a noexcept function, optimizers need not keep the runtime stack in an unwindable state if an exception would propagate out of the function, nor must they ensure that objects in a noexcept function are destroyed in the inverse order of construction should an exception leave the function. The result is more opportunities for optimization, not only within the body of a noexcept function, but also at sites where the function is called. Such flexibility is present only for noexcept functions. Functions with “throw()” exception specifications lack it, as do functions with no exception specification at all.
While looking at Thread and interfaces C++, I noticed something a little strange with my Clang.
I have c++ --version output of
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
Compiling the following
#include <thread>
class Foo {
public:
void operator()() { }
};
int main() {
Foo *foo = new Foo();
std::thread t(foo);
t.join();
delete foo;
}
with c++ thread.cpp yields the following sensible error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:369:5: error: called object type 'Foo *' is not a function or
function pointer
(*__p)();
^~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:377:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<Foo *>' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *>' requested here
std::thread t(foo);
^
1 error generated.
Total sense - Foo * isn't a function pointer.
But, compiling it with c++ -std=c++11 thread.cpp gives this cryptic error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:332:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:342:5: note: in instantiation of function template
specialization 'std::__1::__thread_execute<Foo *>' requested here
__thread_execute(*__p, _Index());
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:354:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<std::__1::tuple<Foo *> >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *&, void>' requested here
std::thread t(foo);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/type_traits:1027:5: note: '~__nat' has been explicitly marked
deleted here
~__nat() = delete;
^
1 error generated.
What's causing this weird error message about a deleted destructor? Should I consider it a bug in Clang to have such an odd message?
Your actual error message is the same in the two cases: whatever template is used to implement std::thread, it cannot be specialized for Foo*.
~__nat() = delete; is only a random difference between the old and new standard, one of the uninteresting things that fail because of the type error.
This compiles fine in MSVC but gcc complains. The code on ideone. I don't understand what is wrong by passing the iterators by reference.
The error
prog.cpp: In function ‘void FindType()’:
prog.cpp:8: error: no matching function for call to ‘FindType(__gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >, __gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >)’
prog.cpp:4: note: candidates are: void FindType(__gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >&, __gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >&)
prog.cpp:5: note: void FindType()
prog.cpp:8: error: return-statement with a value, in function returning 'void'
The code
#include <vector>
using namespace std;
class Var {};
void FindType(vector<Var*>::iterator&b, vector<Var*>::iterator&e){}
void FindType()
{
vector<Var*> ls;
return FindType(ls.begin(), ls.end());
}
Pass const references. The .begin() and .end() calls return rvalues.
Revision: However, as you have observed in the comments below, you cannot do ++b if b is a const reference. Your idea below seems best in that case: pass that iterator by value.
Clang's own diagnostics propaganda contains this exerpt:
Since Clang has range highlighting, it never needs to pretty print your code back out to you. This is particularly bad in G++ (which often emits errors containing lowered vtable references), but even GCC can produce inscrutible error messages in some cases when it tries to do this.
Googling this phrase doesn't give anything very helpful, and the subsequent example is completely unrelated.
Can someone please post an example of what it's talking about?
Thanks.
Here is an example:
struct a {
virtual int bar();
};
struct foo : public virtual a {
};
void test(foo *P) {
return P->bar()+*P;
}
Clang produces:
t.cc:9:18: error: invalid operands to binary expression ('int' and 'foo')
return P->bar()+*P;
~~~~~~~~^~~
GCC 4.2 produces:
t.cc: In function ‘void test(foo*)’:
t.cc:9: error: no match for ‘operator+’ in ‘(((a*)P) + (*(long int*)(P->foo::<anonymous>.a::_vptr$a + -0x00000000000000020)))->a::bar() + * P’
t.cc:9: error: return-statement with a value, in function returning 'void'
GCC does this because its C++ frontend is bolted on top of the C frontend in many cases. Instead of building C++-specific Abstract Syntax Trees (ASTs) for various C++ operations, the parser just lowers them immediately to their C equivalent. In this case, GCC synthesizes an struct to contain the vtable, and the pointer dereference to bar is then lowered into a series of C pointer dereferences, casts, pointer arithmetic etc.
Clang does not have this problem, because it has a very clean AST that directly represents the source code. If you change the example to:
struct a {
virtual int bar();
};
struct foo : public virtual a {
};
void test(foo *P) {
P->bar();
}
.. so that the code is valid, then ask clang to dump its ast with "clang -cc1 -ast-dump t.cc", you get:
...
void test(foo *P)
(CompoundStmt 0x10683cae8 <t.cc:8:19, line:10:1>
(CXXMemberCallExpr 0x10683ca78 <line:9:3, col:10> 'int'
(MemberExpr 0x10683ca40 <col:3, col:6> '<bound member function type>' ->bar 0x10683bef0
(ImplicitCastExpr 0x10683cac8 <col:3> 'struct a *' <UncheckedDerivedToBase (virtual a)>
(ImplicitCastExpr 0x10683ca28 <col:3> 'struct foo *' <LValueToRValue>
(DeclRefExpr 0x10683ca00 <col:3> 'struct foo *' lvalue ParmVar 0x10683c8a0 'P' 'struct foo *'))))))
-Chris