Why the constructor of std::mutex in C++ does not throw? - c++11

The pthread_mutex_init() function returns a non-zero value when it fails to initialize the mutex, while the std::mutex class in C++11 has a constructor of noexcept.
Say one chooses to implement a C++ mutex class on top of pthreads mutex. He wraps a pthread mutex inside the class and tries to initialize it by calling pthread_mutex_init() in constructor. If the function call returns a value other than zero, meaning error, the error can't be reported immediately since the constructor can not throw. One alternative is to throw an exception until the lock method is actually called on the mutex. But this approach just seems wrong.
Is there another way to do this, employing some clever tricks to guarantee that initializing a mutex always succeed?
Update: I am going to answer my own question on this one. According to language standard, in 30.4.1.3 pge 1163, it says ". If initialization of an object of a mutex type fails, an exception of type system_error shall be thrown. "
And a function of noexcept can throw inside the function body, it is just the caller can not catch the exception. If an exception is thrown inside a noexcept function, std::terminate will be called.

The constructor of std::mutex needs to be constexpr (so that a global std::mutex can be statically initialized and used in constructors of other global objects), and therefore cannot call pthread_mutex_init (or similar functions) at all.
Instead, it needs to use PTHREAD_MUTEX_INITIALIZER or equivalent (e.g., SRWLOCK_INIT on Windows) to statically initialize the mutex.

It seems to me that errors from pthread_mutex_init are simply ignored in libstdc++:
https://github.com/psp2sdk/libs/blob/master/include/c%2B%2B/bits/gthr-posix.h#L732
where __gthread_mutex_init_function is via macro __GTHREAD_MUTEX_INIT_FUNCTION invoked here
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/std_mutex.h#L75
that is in std::mutex constructor via its base class.
UPDATE
One can initialize Pthread mutex with PTHREAD_MUTEX_INITIALIZER and then
no error checks are performed
I guess error handling can be postponed to locking functions; quoting from documentation of pthread_mutex_lock and pthread_mutex_trylock ERRORS section:
EINVAL The value specified by mutex does not refer to an initialized mutex object.
This implies that errors in pthread_mutex_init can be safely ignored in std::mutex constructor.

According to C++17 specification:
33.4.3.2 Mutex types [thread.mutex.requirements.mutex]
The mutex types shall be DefaultConstructible and Destructible. If initialization of an object of a mutex type fails, an exception of type system_error shall be thrown. The mutex types shall not be copyable or movable.
So mutex type may throw an exception not std::mutex. std::mutex has noexcept, but std::recursive_mutex does not and they are both mutex types:
33.4.3.2.1 Class mutex [thread.mutex.class]
constexpr mutex() noexcept;
33.4.3.2.2 Class recursive_mutex [thread.mutex.recursive]
recursive_mutex();
Moreover:
20.5.5.12 Restrictions on exception handling [res.on.exception.handling]
Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph, or of a type derived from a type named in the Throws: paragraph that would be caught by an exception handler for the base type.
Functions defined in the C++ standard library that do not have a Throws: paragraph but do have a potentially throwing exception specification may throw implementation-defined exceptions. Implementations should report errors by throwing exceptions of or derived from the standard exception classes (21.6.3.1, 21.8, 22.2).
There is no Throws paragraph and it does not have potentially throwing exception specification.
So std::mutex constructor shall never throw an exception or call std::terminate the same way as any other function from standard library with noexcept specification on conforming C++ implementation.

If you sum it all up this leads to the fact that pthread_mutex_init cannot be called in the std::mutex constructor. There does not need to be a one to one mapping for the construction/initialization. On the contrary!

Related

Throwing a custom exception in Visual C++ 2019

MFC defines functions to throw predefined exceptions. For example, you use ::AfxThrowFileException() to throw an exception of type CFileException. But what if I define my own exception class, which derives from CException? What is the preferred way to throw it?
Are there problems if I simply do this:
if (!m_Settings.IsValid())
throw new CMyException(_T("This operation failed."));
In Visual Studio 2019, the code above generates the following Intellisense warning. But I've yet to see any examples throwing an exception using make_unique.
Warning C26409 Avoid calling new and delete explicitly, use std::make_unique instead (r.11).
Can anyone explain this, or refer me to some current documentation?
Exception handling is one of those areas where it shows, that MFC predates C++ by a fair amount. With C++ exceptions being a late addition to the C++ Standard, MFC had already decided on its exception handling strategy:
Allocate exception objects on the freestore.
Throw by pointer.
Catch by pointer.
Any catch clause that handles an exception is required to release resources associated with the exception object.
By contrast, the idiomatic way to handle C++ exceptions follows these guidelines:
Throw exception objects with automatic storage duration by value.
Catch by (const) reference.
Cleanup of resources is handled automatically.
With MFC you can use either of the above. MFC provides exception macros to help make the former less error prone, although there is no strict requirement to use any of them. In fact, the exception macros in version 3.0 have moved on to almost exclusively use C++ exception handling under the hood.
The correct way to throw custom exceptions in MFC depends on the code that calls it. If that code is using the MFC exception macros, you will need to throw a pointer to the dynamically allocated exception object, e.g.
throw new CMyException(_T("This operation failed."));
or
THROW( (CException*) new CMyException(_T("This operation failed.")) );
and ignore the compiler warning. This is required because the CATCH macros will always expand to catch clauses matching pointer types.
If, on the other hand, calling code uses C++ exception handling, there's no issue throwing either by value or pointer, e.g.
throw CMyException(_T("This operation failed."));
// or
throw new CMyException(_T("This operation failed."));
and catching by const reference or pointer:
catch( CException const& ) {
// no cleanup required
}
// or
catch( CException* e ) {
// manual cleanup still required, unless the exception is re-thrown
e->Delete();
}
In the previous snippet it is also allowed to use both catch clauses, allowing you to provision your calling code to deal with a mixture of throwing custom exceptions by value in your code as well as calling into MFC-provided code that raises dynamically allocated exception objects thrown by pointer.
It is even allowed, to some extent, to mix C++ exception handling and MFC exception macros (Exceptions: Using MFC Macros and C++ Exceptions). The information is provided for completeness only. It is not recommended to mix C++ exceptions and MFC exception macros, unless there is a good reason to do so, e.g. when gradually transitioning existing code from MFC exception macro use to C++ exception handling.

Is noexcept specifier always necessary for mov constructor?

I'm reading some libraries for my project.
Most of them specify "noexcept" in any move constructor.
Is it necessary to write "noexcept" in move constructors or is it occasionally just happened in my reading codes?
Thank you.
I think this explains the reason why you see noexcept in move constructors:
"A class provides the Strong Exception Guarantee if after an exception occurs, the objects maintain their original values. The move members of a class explicitly change the state of their argument. Should an exception be thrown after some members have been moved, then the Strong Exception Guarantee may no longer hold as the from object has been modified. It is especially important to use noexcept for types that are intended to be used with the standard library containers. If the move constructor for an element type in a container is not noexcept then the container will use the copy constructor rather than the move constructor."
So to answer your question, you should use noexcept in every case where your constructor could throw an exception. If you don't use one and if an exception occurs, the Strong Exception Guarantee will fail which could cause problems in the error recovery of your code.
Source: http://www.codingstandard.com/rule/12-5-4-declare-noexcept-the-move-constructor-and-move-assignment-operator/

Is it valid to return a unique_ptr pointing to a forward declared class?

Following code does not compile with clang-700.1.81 and it's standard library:
#include <memory>
class something;
std::unique_ptr<something> external_function();
std::unique_ptr<something> local_function()
{
auto thing = external_function();
return thing;
}
The diagnostics by clang:
......./include/c++/v1/memory:2626:46: note: in instantiation of member function 'std::__1::unique_ptr.....requested here
_LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
^
test.cc:10:18: note: in instantiation of member function 'std::__1::unique_ptr<something, std::__1::default_delete<something> >::~unique_ptr' requested here
auto thing = external_function();
^
test.cc:4:7: note: forward declaration of 'something'
class something;
^
I guess it is trying to destroy the unique_ptr after copying it as return value, but is this really necessary? It is going be moved anyways, does it need to check if it can copy before realizing that it is easier to move it?
I could of course do this easily with a naked pointer.
Is there some other way to allow a uniqe_ptr to just "pass through" a translation unit, as shown in the example, without including extra header to get the definition of class something?
------EDIT--------
Also tried with GCC 5.3.0 and gnu libstdc++
Does not compile as well, with similar error messages.
------EDIT----
I think it is just trying to destroy the original thing object.
Thanks to Rudolf for the deleter idea ( a bit messy, but only option for this )
Looking at the library code I found this in unique_ptr's code:
if (__tmp)
__ptr_.second()(__tmp);
where second(_tmp) destructs the object pointed to. Even though it is never called, the compiler needs a definition to compile it. This is silly, but apparently gotta live with it.
From cppreference.com:
std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the Pimpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr. (Conversely, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete).
Thus, with a custom deleter you can use a forward declared class if the full declaration is available for the deleter:
#include <memory>
class Foo;
class FooDeleter
{
public:
void operator()(Foo* pInstance);
};
std::unique_ptr<Foo, FooDeleter> pFoo;
class Foo
{
};
void FooDeleter::operator()(Foo* pInstance)
{
delete pInstance;
}

Are the implicit move ctor/assignmet operations noexcept? What about implicit copy operations?

The question titles says it all. I need to know if the default copy/move assignment/ctors implemented implicitly by the compiler are declared noexcept.
The standard says:
An inheriting constructor (12.9) and an implicitly declared special
member function (Clause 12) have an exception-specification. If f is
an inheriting constructor or an implicitly declared default
constructor, copy constructor, move constructor, destructor, copy
assignment operator, or move assignment operator, its implicit
exception-specification specifies the type-id T if and only if T is
allowed by the exception-specification of a function directly invoked
by f’s implicit definition; f allows all exceptions if any function it
directly invokes allows all exceptions, and f has the
exception-specification noexcept(true) if every function it directly
invokes allows no exceptions.
So if the implicitly declared copy/move assignment/ctors of your class do not need to call anything that is marked noexcept(false) then they will have the noexcept(true) specifier. The functions that need to be called will be the copy/move assignment/ctors of base class and non-static data members.
Obviously they can't just be unconditionally noexcept, that would be both silly and wrong (for example, the implicit copy constructor for a class containing a std::string member might need to allocate memory, so it can't sensibly be noexcept).
They're noexcept if they only call functions that are noexcept, and they're not noexcept if they call any functions that are not noexcept.

How does CreateStdDispatch know what method to invoke?

i'm faced with implementing an IDispatch interface. There are four methods, and fortunately 3 of them are easy:
function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetTypeInfo(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetIDsOfNames(...): HResult;
{
Result := E_NOTIMPL;
}
It's the last method, Invoke that is difficult. Here i am faced with having to actually case the DispID, and call my appropriate method; unmarhsalling parameters from a variant array.
function Invoke(
dispIdMember: DISPID;
riid: REFIID;
lcid: LCID;
wFlags: WORD;
var pDispParams: DISPPARAMS;
var pVarResult: VARIANT;
var pExcepInfo: EXCEPINFO;
var puArgErr: DWORD
): HRESULT;
Not wanting to have to write all the tedious boilerplate code, that i'm sure will have bugs, i went googling - rather than doing any work.
i found this snippit on the MSDN Documentation of IDispatch.Invoke:
Generally, you should not implement Invoke directly.
Excellent! i didn't want to implement it anyway! Continuing reading:
Instead, use the dispatch interface to create functions CreateStdDispatch and DispInvoke. For details, refer to CreateStdDispatch, DispInvoke, Creating the IDispatch Interface and Exposing ActiveX Objects.
The Creating the IDispatch Interface link says:
You can implement IDispatch by any of the following means:
[snip]
Calling the CreateStdDispatch function. This approach is the simplest, but it does not provide for rich error handling or multiple national languages.
[snip]
Excellent, CreateStdDispatch it is:
Creates a standard implementation of the IDispatch interface through a single function call. This simplifies exposing objects through Automation.
HRESULT CreateStdDispatch(
IUnknown FAR* punkOuter,
void FAR* pvThis,
ITypeInfo FAR* ptinfo,
IUnknown FAR* FAR* ppunkStdDisp
);
i was going to call it as:
CreateStdDispatch(
myUnk, //Pointer to the object's IUnknown implementation.
anotherObject, //Pointer to the object to expose.
nil //Pointer to the type information that describes the exposed object (i has no type info)
dispInterface //the IUnknown of the object that implements IDispatch for me
);
What i cannot figure out is how the Windows API implemention of CreateStdDispatch knows what methods to call on my object - especially since CreateStdDispatch doesn't know what object-oriented language i'm using, or its calling conventions.
How will CreateStdDispatch know
what method to call for a given dispid?
the calling convention of my language?
how to handle exceptions from the language that my object oriented object is written in?
Note: i have no choice but to implement a dispinterface; i didn't define the interface. i wish it was a simple early bound IUnknown, but it tisn't.
Doesn't the ITypeInfo parameter passed into CreateStdDispatch expose all of the method information?
So you'd create type info first calling CreateDispTypeInfo and pass that through to CreateStdDispatch which can then use the type information to work out which method to call since CreateDispTypeInfo requires INTERFACEDATA which contains all this information
I could be way wrong since I don't have time to look into it but that would make sense to me.
I'll investigate this later and update the answer.
The short answer to your question is: neither CreateStdDispatch() nor the IDispatch implementation it creates knows anything at all about the methods to be called.
The object that you get back simply stores the parameters that you passed to CreateStdDispatch(), and for all IDispatch methods it only turns around and makes the corresponding calls on the ITypeInfo that you gave it. That is all.
If you pass nil for ptinfo as shown in your code then you only get E_INVALIDARG, since the implementing object cannot do anything at all without an ITypeInfo to which to delegate all the work.
If you inspect the code for CStdDisp in oleaut32.dll then you will find that it calls API functions like DispInvoke() (which also live in that DLL) instead of invoking the ITypeInfo methods directly, but these functions are all simple wrappers for calls to the ITypeInfo methods, without any further functionality.
In case anyone wonders: neither CreateStdDispatch() nor CStdDisp performs any additional magic; all they do is give you an IDispatch that does whatever the ITypeInfo that you passed in can do. Think of it as a kind of an adapter that allows you to plug an ITypeInfo into an IDispatch socket.
It is true that TAutoIntfObject.Create() needs a type library. However, all that the constructor does is call GetTypeInfoOfGuid() on it in order to get a type info pointer, to which the object then delegates most of the work related to dispatch things.
Borland in their wisdom made the member variable for the type info pointer private, which means that you really need to hand the constructor some type library or other that contains the interface in question, instead of simply writing another constructor or overriding some virtual function. On the other hand it shouldn't be too hard to load the type library via the registry or to dump parts of it to a TLB file. Inspecting a TLB with OleView gives you actual compilable IDL which is often also Borland-compilable RIDL.
CreateStdDispatch() does not know anything about exceptions either. The catching of exceptions thrown from COM methods and their conversion to HRESULT and/or IErrorInfo is compiler magic induced by Delphi's safecall keyword on the implementing method.
The same goes for the translation of HRESULTs to exceptions when calling COM methods specified as safecall in their interface declarations. The compiler simply inserts a call to #CheckAutoResult after every invocation of a safecall method; this function checks the HRESULT and throws EOleSysError if appropriate.
Simply switch the Delphi debugger to disassembly ('CPU view') to inspect all the magic that the compiler does for you!

Resources