2011-12-18 12 views
5

C++ 11 standard określa unique_lock::unlock jak (§ 30.4.2.2.2, p 1159).Czy unique_lock :: unlock underspecified w standardzie C++ 11?

void unlock(); 
Effects: pm->unlock() 
Postcondition: owns == false 
Throws: system_error when an exception is required (30.2.2). 
Error conditions: 
    — operation_not_permitted — if on entry owns is false. 

Wszystkie pozostałe operacje blokowania określić, że wyjątek jest co najmniej dwa razy:

  • muteksu NULL (rzuty system_error z errc::operation_not_permitted)
  • muteksu jest już zablokowany (rzuty system_error z errc::operation_not_permitted)

Problem z nieprawidłowym muteksem jest oczywiście możliwy również dla unlock, jednak norma określa zachowanie programu tylko w przypadku problemów z blokowaniem. Czy to prawdziwy błąd w standardzie czy coś mi brakuje?

+0

Nie jestem pewien, czy podążam. Dlaczego jest "oczywiście możliwe", aby 'unlock' został wywołany, gdy muteks jest nieważny? Możesz wywnioskować, że jako efekt 'unlock()' jest 'pm-> unlock()', aby uniknąć niezdefiniowanego zachowania 'pm' nie może mieć wartości null i musi być spełniona umowa dla' BasicLockable' '* pm' , więc blokada musi być własnością bieżącego agenta wykonawczego. Czy jest jakaś subtelność, której mi brakuje? –

Odpowiedz

7

Chociaż nie zostało to wyraźnie powiedziane, unique_lock ma następujące niezmienniki:

if pm == nullptr then owns == false 
if owns == true then pm != nullptr 

po prostu nie ma sposób, aby uzyskać unique_lock w stan, który narusza te niezmienniki, z wyjątkiem zachowania nieokreślonego. Tak więc klauzula:

— operation_not_permitted — if on entry owns is false. 

obejmuje przypadek, że pm == nullptr.

Należy pamiętać, że ~unique_lock() wywołuje tylko pm->unlock(), jeśli owns jest prawdziwe. Jeśli owns jest prawdziwe, wówczas pm != nullptr, a tym samym unlock(), nie może wykonać rzutu.

0

pm jest mutex_type i definicja do odblokowania w std::mutex jest:

void unlock() noexcept; 

Oznacza to, że funkcja unlock nie może rzucać żadnych wyjątków, dlatego unique_lock::unlock nie musi dziedziczyć każdy z tych wyjątków. Jeśli chodzi o to, dlaczego można w ogóle wyrzucić jakiś wyjątek, jest to tajemnicą.

To jest trochę uciążliwe, że destruktor dla unique_lock może rzucić wyjątek (ponieważ domyślam się, że może on musi zadzwonić pod numer unlock, gdzie może również). To wydaje mi się złe, ponieważ używanie obiektu blokady do prawidłowego odblokowania podczas obsługi wyjątku jest bardzo popularnym idiomem. To naprawdę źle, że blokada może rzucić wyjątek podczas rozwijania stosu - zwłaszcza, że ​​podstawowy muteks nie jest dozwolony.

Coś tu jest zdecydowanie nie tak.

Wciąż pracuję z ostatniego projektu publicznego, może ten został ustalony

+0

Patrzę na rzeczywisty standard C++ 11. Ani 'unique_ptr :: ~ unique_ptr' to' noexcept', ani propozycja niejawnego dodania noexcept dla destruktorów została zaimplementowana, więc nie została naprawiona.Uważam jednak, że jest to inny problem. Standard nie określa, co dzieje się w przypadku, gdy 'unique_ptr' nie ma powiązanego muteksu, a' unlock' jest wywoływane na tej blokadzie. –

Powiązane problemy