C++ Exception-Safe Assignment Overloading

Introduction

Implementing C++ assignment overloading can be error-prone if the object involves data on the memory heap.

In this blog post, I would like to quickly discuss how to implement exception safe C++ assignment overloading and how to apply the copy-and-swap idiom to implement it more elegantly.

C++ Assignment Overloading

Exception-safe and self-assignment.

Make sure the resource management inside the assignment overloading has taken throwing exceptions into account to prevent the data loss from the object. In the following example, we strictly follow allocate, populate and deallocate. If we deallocate the cstring member variable before allocate the new buffer, and allocating new buffer throws exception, we lose the cstring data forever.


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<cstddef>
#include <cstring>
#include <iostream>

class String
{

public:
String(const char* s = "") : String(s, std::strlen(s) + 1) {}

String(const String& other) : String(other.cstring) {}

~String() { delete[] cstring; }

String& operator=(const String& other)
{
// Ignore self assignment.
// A little bit problematic here because of the data on the heap.
// Need to overload == and the comparison might take a long time.
// This step might just be skipped.
if (this == &other)
return *this;
std::size_t n{std::strlen(other.cstring) + 1};
// The order matters to make sure the assignment is exception-safe.
char* new_cstring = new char[n]; // allocate
std::memcpy(new_cstring, other.cstring, n); // populate
delete[] cstring; // deallocate
cstring = new_cstring;
return *this;
}

bool operator==(const String& other) const noexcept
{
if (std::strlen(cstring) != std::strlen(other.cstring))
{
return false;
}
for (std::size_t i = 0; i < std::strlen(cstring); ++i)
{
if (cstring[i] != other.cstring[i])
{
return false;
}
}
return true;
}

operator const char*() const noexcept { return cstring; }

private:
String(const char* s, std::size_t n) : cstring(new char[n])
{
std::memcpy(cstring, s, n);
}

char* cstring;
};

int main()
{
String str_1{"abcd"};
String str_2{"def"};
str_1 = str_2;
}

Valgrind verified that there is no memory leak during runtime.


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

$ valgrind --leak-check=full ./string
==56318== Memcheck, a memory error detector
==56318== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==56318== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==56318== Command: ./string
==56318==
==56318==
==56318== HEAP SUMMARY:
==56318== in use at exit: 0 bytes in 0 blocks
==56318== total heap usage: 4 allocs, 4 frees, 72,717 bytes allocated
==56318==
==56318== All heap blocks were freed -- no leaks are possible
==56318==
==56318== For lists of detected and suppressed errors, rerun with: -s
==56318== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Copy-And-Swap Idiom

A more elegant way of implementing assignment overloading is to apply the “copy-and-swap” idiom. We create a public or private noexcept swap member function and use the member function for the temporary copy of the assignment source.


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<cstddef>
#include <cstring>
#include <iostream>

class String
{

public:
String(const char* s = "") : String(s, std::strlen(s) + 1) {}

String(const String& other) : String(other.cstring) {}

~String() { delete[] cstring; }

String& operator=(const String& other)
{
// Ignore self assignment.
// A little bit problematic here because of the data on the heap.
// Need to overload == and the comparison might take a long time.
// This step might just be skipped.
if (this == &other)
return *this;
// copy-and-swap idiom.
String temp_string{other};
swap(temp_string);
return *this;
}

// no exception is allowed for swap.
void swap(String& other) noexcept
{
char* temp_cstring = cstring;
cstring = other.cstring;
other.cstring = temp_cstring;
}

bool operator==(const String& other) const noexcept
{
if (std::strlen(cstring) != std::strlen(other.cstring))
{
return false;
}
for (std::size_t i = 0; i < std::strlen(cstring); ++i)
{
if (cstring[i] != other.cstring[i])
{
return false;
}
}
return true;
}

operator const char*() const noexcept { return cstring; }

private:
String(const char* s, std::size_t n) : cstring(new char[n])
{
std::memcpy(cstring, s, n);
}

char* cstring;
};

int main()
{
String str_1{"abcd"};
String str_2{"def"};
str_1 = str_2;
}

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

$ valgrind --leak-check=full ./string
==56745== Memcheck, a memory error detector
==56745== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==56745== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==56745== Command: ./string
==56745==
==56745==
==56745== HEAP SUMMARY:
==56745== in use at exit: 0 bytes in 0 blocks
==56745== total heap usage: 4 allocs, 4 frees, 72,717 bytes allocated
==56745==
==56745== All heap blocks were freed -- no leaks are possible
==56745==
==56745== For lists of detected and suppressed errors, rerun with: -s
==56745== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

https://leimao.github.io/blog/CPP-Exception-Safe-Assignment-Overloading/

Licensed under

Like this article support the author with, advertisement.

  • 1 Introduction
  • 2.1 Exception-Safe and Self-Assignment
  • 2.2 Copy-And-Swap Idiom

Vorbrodt's C++ Blog

Practical Modern C++

Exception safe assignment.

Longer title: exception safe assignment operator of resource owning objects . Uff. Because the object owns a resource, how do we write an exception safe assignment operator which will have to free up the old and allocate the new resource. By exception safe I don’t mean that it will never throw, that’s not possible. Instead, I mean safe in the sense that it either succeeds OR in case of exceptions the state of assigned to object is exactly as it was prior to the assignment. Like this:

main() S s1, s2; s1 = s2;

If assignment operator s1 = s2 throws an exception, we want the state of s1 and s2 to be as it was in line #3 .

The trick is two fold: 1) a copy constructor is needed, and 2) noexcept swap function. Like this:

(const S& s) m_resource(new int) *m_resource = *s.m_resource; swap(S& s) noexcept std::swap(m_resource, s.m_resource);

Here the copy constructor allocates the new resource first, then copies its content; the swap function just swaps pointers to the resources, which is always a noexcept operation. Having implemented a copy constructor and swap function we can now implement every assignment operator to have a strong exception guarantee like this:

& operator = (const S& s) S temp(s); // May throw swap(temp); // Will never throw return *this;

Here’s how it works: we first make a temporary copy, which does the resource allocation. At this stage exceptions can be thrown, but we have not yet modified the assigned to object. Only after the resource allocation succeeds do we perform the noexcept swap. The destructor of your temporary object will take care of cleaning up the currently owned resource (that’s RAII at its best).

Complete listing ( assignment.cpp ):

namespace std; S S() : m_resource(new int) { cout << "S()" << endl; *m_resource = 1; } S(const S& s) : m_resource(new int) { cout << "S(const S&)" << endl; *m_resource = *s.m_resource; } S(S&&) = delete; S& operator = (const S& s) { cout << "operator = (const S&)" << endl; S temp(s); // May throw swap(temp); // Will never throw return *this; } S& operator = (S&&) = delete; ~S() { cout << "~S()" << endl; delete m_resource; } void swap(S& s) noexcept { std::swap(m_resource, s.m_resource); } int* m_resource; ; main() S s1, s2; s1 = s2;
S() S() operator = (const S&) S(const S&) ~S() ~S() ~S() Program output.

Share this:

Related articles, token bucket: or how to throttle, inline – not what it used to be, visitor pattern and multiple-dispatch explained, leave a reply cancel reply.

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

How to: Design for exception safety

  • 7 contributors

One of the advantages of the exception mechanism is that execution, together with data about the exception, jumps directly from the statement that throws the exception to the first catch statement that handles it. The handler may be any number of levels up in the call stack. Functions that are called between the try statement and the throw statement are not required to know anything about the exception that is thrown. However, they have to be designed so that they can go out of scope "unexpectedly" at any point where an exception might propagate up from below, and do so without leaving behind partially created objects, leaked memory, or data structures that are in unusable states.

Basic techniques

A robust exception-handling policy requires careful thought and should be part of the design process. In general, most exceptions are detected and thrown at the lower layers of a software module, but typically these layers do not have enough context to handle the error or expose a message to end users. In the middle layers, functions can catch and rethrow an exception when they have to inspect the exception object, or they have additional useful information to provide for the upper layer that ultimately catches the exception. A function should catch and "swallow" an exception only if it is able to completely recover from it. In many cases, the correct behavior in the middle layers is to let an exception propagate up the call stack. Even at the highest layer, it might be appropriate to let an unhandled exception terminate a program if the exception leaves the program in a state in which its correctness cannot be guaranteed.

No matter how a function handles an exception, to help guarantee that it is "exception-safe," it must be designed according to the following basic rules.

Keep resource classes simple

When you encapsulate manual resource management in classes, use a class that does nothing except manage a single resource. By keeping the class simple, you reduce the risk of introducing resource leaks. Use smart pointers when possible, as shown in the following example. This example is intentionally artificial and simplistic to highlight the differences when shared_ptr is used.

Use the RAII idiom to manage resources

To be exception-safe, a function must ensure that objects that it has allocated by using malloc or new are destroyed, and all resources such as file handles are closed or released even if an exception is thrown. The Resource Acquisition Is Initialization (RAII) idiom ties management of such resources to the lifespan of automatic variables. When a function goes out of scope, either by returning normally or because of an exception, the destructors for all fully-constructed automatic variables are invoked. An RAII wrapper object such as a smart pointer calls the appropriate delete or close function in its destructor. In exception-safe code, it is critically important to pass ownership of each resource immediately to some kind of RAII object. Note that the vector , string , make_shared , fstream , and similar classes handle acquisition of the resource for you. However, unique_ptr and traditional shared_ptr constructions are special because resource acquisition is performed by the user instead of the object; therefore, they count as Resource Release Is Destruction but are questionable as RAII.

The three exception guarantees

Typically, exception safety is discussed in terms of the three exception guarantees that a function can provide: the no-fail guarantee , the strong guarantee , and the basic guarantee .

No-fail guarantee

The no-fail (or, "no-throw") guarantee is the strongest guarantee that a function can provide. It states that the function will not throw an exception or allow one to propagate. However, you cannot reliably provide such a guarantee unless (a) you know that all the functions that this function calls are also no-fail, or (b) you know that any exceptions that are thrown are caught before they reach this function, or (c) you know how to catch and correctly handle all exceptions that might reach this function.

Both the strong guarantee and the basic guarantee rely on the assumption that the destructors are no-fail. All containers and types in the Standard Library guarantee that their destructors do not throw. There is also a converse requirement: The Standard Library requires that user-defined types that are given to it—for example, as template arguments—must have non-throwing destructors.

Strong guarantee

The strong guarantee states that if a function goes out of scope because of an exception, it will not leak memory and program state will not be modified. A function that provides a strong guarantee is essentially a transaction that has commit or rollback semantics: either it completely succeeds or it has no effect.

Basic guarantee

The basic guarantee is the weakest of the three. However, it might be the best choice when a strong guarantee is too expensive in memory consumption or in performance. The basic guarantee states that if an exception occurs, no memory is leaked and the object is still in a usable state even though the data might have been modified.

Exception-safe classes

A class can help ensure its own exception safety, even when it is consumed by unsafe functions, by preventing itself from being partially constructed or partially destroyed. If a class constructor exits before completion, then the object is never created and its destructor will never be called. Although automatic variables that are initialized prior to the exception will have their destructors invoked, dynamically allocated memory or resources that are not managed by a smart pointer or similar automatic variable will be leaked.

The built-in types are all no-fail, and the Standard Library types support the basic guarantee at a minimum. Follow these guidelines for any user-defined type that must be exception-safe:

Use smart pointers or other RAII-type wrappers to manage all resources. Avoid resource management functionality in your class destructor, because the destructor will not be invoked if the constructor throws an exception. However, if the class is a dedicated resource manager that controls just one resource, then it's acceptable to use the destructor to manage resources.

Understand that an exception thrown in a base class constructor cannot be swallowed in a derived class constructor. If you want to translate and re-throw the base class exception in a derived constructor, use a function try block.

Consider whether to store all class state in a data member that is wrapped in a smart pointer, especially if a class has a concept of "initialization that is permitted to fail." Although C++ allows for uninitialized data members, it does not support uninitialized or partially initialized class instances. A constructor must either succeed or fail; no object is created if the constructor does not run to completion.

Do not allow any exceptions to escape from a destructor. A basic axiom of C++ is that destructors should never allow an exception to propagate up the call stack. If a destructor must perform a potentially exception-throwing operation, it must do so in a try catch block and swallow the exception. The standard library provides this guarantee on all destructors it defines.

Modern C++ best practices for exceptions and error handling How to: Interface Between Exceptional and Non-Exceptional Code

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

CS102: Introduction to Computer Science II

exception safe assignment

Exception Handling in C++

This page might seem like it duplicates some of what we have just seen, but it is valuable because it gives a different perspective on the topic. Read chapter 1 on pages 15-60.

Exception safety

In Chapter 7 we'll take an in-depth look at the containers in the Standard C++ library, including the  stack  container. One thing you'll notice is that the declaration of the  pop( )  member function looks like this:

You might think it strange that  pop( )  doesn't return a value. Instead, it just removes the element at the top of the stack. To retrieve the top value, call  top( )  before you call  pop( ) . There is an important reason for this behavior, and it has to do with  exception safety , a crucial consideration in library design. There are different levels of exception safety, but most importantly, and just as the name implies, exception safety is about correct semantics in the face of exceptions.

Suppose you are implementing a stack with a dynamic array (we'll call it  data  and the counter integer  count ), and you try to write  pop( )  so that it returns a value. The code for such a  pop( )  might look something like this:

What happens if the copy constructor that is called for the return value in the last line throws an exception when the value is returned? The popped element is not returned because of the exception, and yet  count  has already been decremented, so the top element you wanted is lost forever! The problem is that this function attempts to do two things at once: (1) return a value, and (2) change the state of the stack. It is better to separate these two actions into two separate member functions, which is exactly what the standard  stack  class does. (In other words, follow the design practice of  cohesion ­–  every function should do  one thing well .) Exception-safe code leaves objects in a consistent state and does not leak resources.

You also need to be careful writing custom assignment operators. In Chapter 12 of Volume 1, you saw that  operator=  should adhere to the following pattern:

  • Make sure you're not assigning to self. If you are, go to step 6. (This is strictly an optimization.)
  • Allocate new memory required by pointer data members.
  • Copy data from the old memory to the new.
  • Delete the old memory.
  • Update the object's state by assigning the new heap pointers to the pointer data members.
  • Return  *this .

It's important to not change the state of your object until all the new pieces have been safely allocated and initialized. A good technique is to move steps 2 and 3 into a separate function, often called  clone( ) . The following example does this for a class that has two pointer members,  theString  and  theInts :

For convenience,  HasPointers  uses the  MyData  class as a handle to the two pointers. Whenever it's time to allocate more memory, whether during construction or assignment, the first  clone  function is ultimately called to do the job. If memory fails for the first call to the  new  operator, a  bad_alloc  exception is thrown automatically. If it happens on the second allocation (for  theInts ), we must clean up the memory for  theString ­–  hence the first  try  block that catches a  bad_alloc  exception. The second  try  block isn't crucial here because we're just copying  int s and pointers (so no exceptions will occur), but whenever you copy objects, their assignment operators can possibly cause an exception, so everything needs to be cleaned up. In both exception handlers, notice that we  rethrow  the exception. That's because we're just managing resources here; the user still needs to know that something went wrong, so we let the exception propagate up the dynamic chain. Software libraries that don't silently swallow exceptions are called  exception neutral . Always strive to write libraries that are both exception safe and exception neutral.

If you inspect the previous code closely, you'll notice that none of the  delete  operations will throw an exception. This code depends on that fact. Recall that when you call  delete  on an object, the object's destructor is called. It turns out to be practically impossible to design exception-safe code without assuming that destructors don't throw exceptions. Don't let destructors throw exceptions. (We're going to remind you about this once more before this chapter is done).


November 3

October 23
(Addison-Wesley, 2002) for the most current solution to this GotW issue. The solutions in the book have been revised and expanded since their initial appearance in GotW. The book versions also incorporate corrections, new material, and conformance to the final ANSI/ISO C++ standard.

Exception-Safe Class Design, Part 1: Copy Assignment  Difficulty: 7 / 10

Is it possible to make any C++ class strongly exception-safe, for example for its copy assignment operator? If so, how? What are the issues and consequences?

JG Questions

1. What are the three common levels of exception safety? Briefly explain each one and why it is important.

2. What is the canonical form of strongly exception-safe copy assignment?

Guru Questions

3. Consider the following class:

Assume that any T1 or T2 operation might throw. Without changing the structure of the class, is it possible to write a strongly exception-safe Widget::operator=( const Widget& )? Why or why not? Draw conclusions.

4. Describe and demonstrate a simple transformation that works on any class in order to make strongly exception-safe copy assignment possible and easy for that class. Where have we seen this transformation technique before in other contexts? Cite GotW issue number(s).

Review: Exception Safety Canonical Forms

The canonical Abrahams Guarantees are as follows.

1. Basic Guarantee: If an exception is thrown, no resources are leaked, and objects remain in a destructible and usable -- but not necessarily predictable -- state. This is the weakest usable level of exception safety, and is appropriate where client code can cope with failed operations that have already made changes to objects' state.

2. Strong Guarantee: If an exception is thrown, program state remains unchanged. This level always implies global commit-or-rollback semantics, including that no references or iterators into a container be invalidated if an operation fails.

In addition, certain functions must provide an even stricter guarantee in order to make the above exception safety levels possible:

3. Nothrow Guarantee: The function will not emit an exception under any circumstances. It turns out that it is sometimes impossible to implement the strong or even the basic guarantee unless certain functions are guaranteed not to throw (e.g., destructors, deallocation functions). As we will see below, an important feature of the standard auto_ptr is that no auto_ptr operation will throw.

It involves two steps: First, provide a nonthrowing Swap() function that swaps the guts (state) of two objects:

Second, implement operator=() using the "create a temporary and swap" idiom:

The Cargill Widget Example

This brings us to the Guru questions, starting with a new exception safety challenge proposed by Tom Cargill:

Short answer: In general, no, it can't be done without changing the structure of Widget.

In the Example 3 case, it's not possible to write a strongly exception-safe Widget::operator=() because there's no way that we can change the state of both of the t1_ and t2_ members atomically. Say that we attempt to change t1_, then attempt to change t2_. The problem is twofold:

1. If the attempt to change t1_ throws, t1_ must be unchanged. That is, to make Widget::operator=() strongly exception-safe relies fundamentally on the exception safety guarantees provided by T1, namely that T1::operator=() (or whatever mutating function we are using) either succeeds or does not change its target. This comes close to requiring the strong guarantee of T1::operator=(). (The same reasoning applies to T2::operator=().)

2. If the attempt to change t1_ succeeds, but the attempt to change t2_ throws, we've entered a "halfway" state and cannot in general roll back the change already made to t1_.

Therefore, the way Widget is currently structured, its operator=() cannot be made strongly exception-safe.

Our goal: To write a Widget::operator=() that is strongly exception-safe, without making any assumptions about the exception safety of any T1 or T2 operation. Can it be done? Or is all lost?

A Complete Solution: Using the Pimpl Idiom

The good news is that, even though Widget::operator=() can't be made strongly exception-safe without changing Widget's structure, the following simple transformation always works:

The way to solve the problem is hold the member objects by pointer instead of by value, preferably all behind a single pointer with a Pimpl transformation (described in GotW issues like 7 , 15 , 24 , 25 , and 28 ).

Here is the canonical Pimpl exception-safety transformation:

Now we can easily implement a nonthrowing Swap(), which means we can easily implement exception-safe copy assignment: First, provide the nonthrowing Swap() function that swaps the guts (state) of two objects (note that this function can provide the nothrow guarantee because no auto_ptr operations are permitted to throw exceptions):

Second, implement the canonical form of operator=() using the "create a temporary and swap" idiom:

A Potential Objection, and Why It's Unreasonable

Some may object: "Aha! Therefore this proves exception safety is unattainable in general, because you can't solve the general problem of making any arbitrary class strongly exception-safe without changing the class!"

Such a position is unreasonable and untenable. The Pimpl transformation, a minor structural change, IS the solution to the general problem. To say, "no, you can't do that, you have to be able to make an arbitrary class exception-safe without any changes," is unreasonable for the same reason that "you have to be able to make an arbitrary class meet New Requirement #47 without any changes" is unreasonable.

For example:

Unreasonable Statement #1: "Polymorphism doesn't work in C++ because you can't make an arbitrary class usable in place of a Base& without changing it (to derive from Base)."

Unreasonable Statement #2: "STL containers don't work in C++ because you can't make an arbitrary class usable in an STL container without changing it (to provide an assignment operator)."

Unreasonable Statement #3: "Exception safety doesn't work in C++ because you can't make an arbitrary class strongly exception-safe without changing it (to put the internals in a Pimpl class)."

Clearly all the above arguments are equally bankrupt, and the Pimpl transformation is indeed the general solution to strongly exception-safe objects.

So, what have we learned?

Conclusion 1: Exception Safety Affects a Class's Design

Exception safety is never "just an implementation detail." The Pimpl transformation is a minor structural change, but still a change. GotW #8 shows another example of how exception safety considerations can affect the design of a class's member functions.

Conclusion 2: You Can Always Make Your Code (Nearly) Strongly Exception-Safe

There's an important principle here:

Just because a class you use isn't in the least exception-safe is no reason that YOUR code that uses it can't be (nearly) strongly exception-safe.

Anybody can use a class that lacks a strongly exception-safe copy assignment operator and make that use exception-safe. The "hide the details behind a pointer" technique can be done equally well by either the Widget implementor or the Widget user... it's just that if it's done by the implementor it's always safe, and the user won't have to do this:

Conclusion 3: Use Pointers Judiciously

To quote Scott Meyers:

"When I give talks on EH, I teach people two things: "- POINTERS ARE YOUR ENEMIES, because they lead to the kinds of problems that auto_ptr is designed to eliminate.

To wit, bald pointers should normally be owned by manager objects that own the pointed-at resource and perform automatic cleanup. Then Scott continues:

"- POINTERS ARE YOUR FRIENDS, because operations on pointers can't throw. "Then I tell them to have a nice day :-)

Scott captures a fundamental dichotomy well. Fortunately, in practice you can and should get the best of both worlds:

- USE POINTERS BECAUSE THEY ARE YOUR FRIENDS, because operations on pointers can't throw.

- KEEP THEM FRIENDLY BY WRAPPING THEM IN MANAGER OBJECTS like auto_ptrs, because this guarantees cleanup. This doesn't compromise the nonthrowing advantages of pointers because auto_ptr operations never throw either (and you can always get at the real pointer inside an auto_ptr whenever you need to).

More Exceptional C++ by Herb Sutter

Get full access to More Exceptional C++ and 60K+ other titles, with a free 10-day trial of O'Reilly.

There are also live events, courses curated by job role, and more.

Chapter 22. Exception-Safe Class Design, Part 1: Copy Assignment

Difficulty: 7

Is it possible to make any C++ class strongly exception-safe, for example, for its copy assignment operator? If so, how? What are the issues and consequences? To illustrate, this Item explains and then solves the Cargill Widget Example.

What are the three common levels of exception safety? Briefly explain each one and why it is important.

What is the canonical form of strongly exception-safe copy assignment?

Consider the following class:

Assume that any T1 or T2 operation might throw. Without changing the structure of the class, ...

Get More Exceptional C++ now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.

Don’t leave empty-handed

Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.

It’s yours, free.

Cover of Software Architecture Patterns

Check it out now on O’Reilly

Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.

exception safe assignment

  • Sign In / Suggest an Article

Current ISO C++ status

Upcoming ISO C++ meetings

Upcoming C++ conferences

Compiler conformance status

ISO C++ committee meeting

June 24-29, St. Louis, MO, USA

July 2-5, Folkestone, Kent, UK

Exception safety: The strong guarantee and move semantics

By Blog Staff | Nov 4, 2013 01:27 AM | Tags: intermediate

meyers-gn13.PNG

Since the gorier details of the answer lie in "watch Scott's talk ," we merrily abuse a snapshot of Dr. Meyers during said talk as the highlight graphic for this post.

Exception safe code and move semantics I want to write container class. This container has insert method that have two specializations -- first uses copy constructors to copy data from one container to another container element wise. If copy constructor throws exception I just undo all changes to the container like nothing happens. The second specialization uses move constructor and thats the place where things got complicated. When I move items from one container to another container element by element, move constructor can throw exception. If this happens -- I've got really messy state when some elements are moved and other elements stays in it's original places. If I try to move elements back -- I can get another exception. Is it possible to write something like this in exception safe manner or exception safety and move semantics are mutually exclusive?

Share this Article

Add a comment, comments (0).

There are currently no comments on this entry.

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

Implementing an exception safe and exception neutral stack, from Tom Cargill's 1994 Article "Exception Handling: A False Sense of Security" in the C++ Report

campjake/Exception-Safe-Stack

Folders and files.

NameName
21 Commits

Repository files navigation

The problem.

  • Make Stack exception safe. Stack objects will always be invariant regardless of any exceptions thrown during the execution of its member functions.
  • Make Stack exception neutral. If exceptions are thrown, they are propagated through to the caller, who will deal with them with the benefit of context with regards to the template parameter T .

Get the Code

Requirements:.

  • C++14 required by GoogleTest

Running The Program

Here is a very basic, inefficient way to get it running ASAP ( source ):

  • Clone this repository: git clone https://github.com/campjake/Exception-Safe-Stack
  • You only need to do this once
  • You can do a partial build instead if you write new components.
  • Run the tests: cd build && ctest

My Motivations

I am an undergraduate student studying Computer Science, so I learned about exception handling. It's not an overly difficult concept, that is, the fundamentals of exception handling are not difficult to read about, and then mimic to some extent.

However, I felt that my education didn't properly inform me that exception handling wasn't the end all be all of the topic. Before reading about Exception Safety in Herb Sutter's book (see Reading Resources ), I had never even heard of the different levels of Exception Safety.

So, heeding the call, I created this repo to thoroughly document what I learned about the concept.

Some Personal Notes and Questions to Readers

  • Is using smart pointers cheating? This problem predates Modern C++, so I'm wondering if I am missing the point here. I'll try to focus on Exception Safety and use whatever I have to ensure strong guarantees wherever I can. It was a great exercise for familiarizing myself with smart pointers more, and I think Modern C++ made this significantly easier.
  • Whenever you think you're safe, const qualifiers are waiting to drag you down to hell. I'm glad I wrote tests before writing source code.
  • This wasn't that different from a normal homework assignment on writing a stack class, but the perspective shift to focus on exception safety still helped me learn some things.
  • The logic behind vsize_ and vused_ didn't make sense until I checked Herb Sutter's solution. He used an array, and I used a Linked List. So whenever vused_ was equal to vsize_ a new array needed to be dynamically allocated, the elements needed to be copied (or moved) to the new array, and the old array needed to be deallocated. Move semantics helped out a lot here, and yes, this puzzle predates that, too. My result thus simulates some kind of weird amalgamation of a super limited free store. Had I understood sooner, I wouldn't have even used both variables, but I leave it for you, the reader, to learn from.

Evaluation and Discussion

Is it Exception Safe and Exception Neutral? Yes. I inadvertently simplified the challenge further than expected by implementing this as a linked list, and using smart pointers, but I believe I passed the minimum threshold for this challenge. I have some more thoughts detailed in the following subsections.

Default Construction

The default constructor doesn't actually allocate any memory, so we don't need to worry about an std::bad_alloc being thrown here. In fact, the default constructor for an std::unique_ptr is noexcept , so it will call std::terminate if an exception gets thrown here, somehow.

Copy Construction & Copy Assignment

Smart pointers really did some heavy lifting here. I immediately reached for std::unique_ptr because of this note from cppreference:

std::unique_ptr is commonly used to manage the lifetime of objects, including: providing exception safety to classes and functions that handle objects with dynamic lifetime, by guaranteeing deletion on both normal exit and exit through exception.

Why does it matter? You'll notice there are no explicit deallocations made in the functions Erase() or Pop() . It was easy to write, and (hopefully) it's easy to read. Thank you smart pointers!

You might be thinking, "Okay tough guy... you might be using smart pointers, but that doesn't mean you won't throw an exception!"

And you're right, but it's still Exception Safe and Exception Neutral. If an std::bad_alloc is thrown, it gets propogated up the call stack to the calling function. Objects in the current scope are destroyed, including our size counter, and any std::unique_ptr hanging around pointing to the free store will deallocate the memory. As Herb Sutter said,

"All that's left is raw memory, smoke, and ashes."

C'mon, you know that size_t is an alias for an unsigned integral, right? Those aren't classes, so they don't have member functions that could throw. I decided to tack on noexcept , please inform me if this hubris will lead to my downfall.

Push & Pop

Once again, smart pointers to the rescue. Studying them saved me a lot of time here. Had I opted for a solution with an array and raw pointers, I would have spent way more time fiddling with assertions and dynamic allocation and moving of resources.

Retrospective & Key Takeaways

My solution and the book's solution are very different, and it highlights the importance of learning C++. It is an evolving language, and taking advantage of new mechanics can lead to cleaner, better code. Using std::unique_ptr eliminated most of the traps set by the author, and the few that remained are commonly taught as bad practice (seriously, don't throw exceptions in a destructor. You should always guarantee that you can deallocate dynamic allocations of memory).

The repository probably wouldn't meet the minimum requirements of a robust testing environment, but was never written to be production-level code. I'd change that, and I'd also try and rewrite this with a pImpl interface. If I ever come back to this, that will be the roadmap!

Revisiting with "More Modern" CMake (CMake 3.14)

I decided to revisit this example much sooner than expected because of a great video by Deniz Bahadir about CMake. I saw this little exercise as a great introduction to CMake, since previous commits in this only used a single, top-level CMakeLists.txt . And begrudgingly so, because it is required to configure Google Tests. But it actually corrected some overlooked bugs!

Cleaner Project Structure

Following the video, I created library/ , library/include , and library/src directories (no this isn't out of date, I know src/ is gone). The CMakeLists.txt file in library/ propagates the targets up to the top-level CMakeLists.txt , and builds the project, so I can run tests and pat myself on the back.

Deeper Issues Revealed by CMake

GCC really held my hand and told me, "Hey bud, it's okay! You don't really need to fix these architecture level problems you have here!" Previously, I had separated the Stack class definition and the member function definitions into different files, not realizing that I had just defeated the whole purpose of using templates to create an interface. That's because templates aren't classes. The compiler will create a family of classes or functions that the user of the interface wants to instantiate.

I sat here scratching my head for the better half of the morning wondering what little trick I needed to do to just get it to do what I wanted, not realizing that if you refuse to create the template as an interface, you need to make a forward declaration for every valid type of template class the user can generate. That's a first year C++ mistake! I can't believe I forgot that! I moved to a header only implementation to rectify that. After figuring out some of the weird CMake syntax, I was able to identify the missing libraries and repeated definitions, and clean it up for a clean build.

More Takeaways

How is the Stack, an elementary data structure that every CS student will study and implement in 6 different languages, still a good teaching tool for Modern C++ and Modern CMake? Don't answer that, I know, I should have studied harder. Maye I'll return to this again and learn another chunk of concepts. I think Sutter's book gave this challenge a 7/10 difficulty rating. At first, I thought it was a 5 since smart pointers simplified a lot. Now seeing my mistakes with CMake, I think 7 is fair. Turns out, the problem doesn't suddenly get simpler to understand with new fancy tools that make it simpler to implement.

Reading Resources

  • Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions (Herb Sutter)
  • This article is actually a response to a 1993 article by David Reed, which you will find if you read this.
  • More Modern CMake (Deniz Bahadir, Meeting C++ 2018)

Thank you to Dr. Ray Klefstad for recommending me the book by Herb Sutter, setting me off on this weird path in the first place!

  • CMake 16.9%

The Stubborn Coder

The Stubborn Coder

Refusing to Read the Docs Since 2006

Staying Safe in C++

What is exception safety.

Exceptions are gross. One of the problems with exceptions is that, as they break out of the normal control flow, they can potentially leave our program in a bad state. How do we avoid this?

Well, we can guarantee that we never throw an exception, either because our code is perfect, or, we catch and smoothly handle all exceptions at the point they are thrown. This is a worthy goal, but might not be entirely practical. So the alternative is to follow the philosophy of exception safety . This is the design philosophy that says that we can throw exceptions, but, when we do, we must leave things in a good state.

There are two different flavours of exception safety, strong exception safety and weak exception safety. Strong exception safety is a guarantee that when an exception is thrown during some operation, the overall state will be back to what it was before the operation started. In other words, our methods are atomic or transactional. Weak exception safety is the guarantee that when we throw an exception we will leave things in a valid state. In particular, both forms of exception safety guarantee that we will not leak any resources.

Usually we manage state via classes, and that is also how we think about exception safety. How we make a class exception safe depends on the state that our class manages, and the functionality it exposes via it’s methods.

An Example of Exception Safety

Here’s an example from a job interview I did recently. Suppose we have two strongly exception safe classes: ResourceManager 1 and ResourceManager2 . In our code we want to define another class, which we, optimistically, name, SafeCopyingClass , like so:

The question is, how can we implement a copy constructor for this class in an exception safe way?

We have to copy three member variables. We know that copying an integer like the member a should not throw. This means that we should leave the copy of a until the very end, that way if something goes wrong with the other two copies, we won’t have to roll it back. So, to start, we are going to have something like this:

Now what about copying the members b and c ? Suppose we naively copy the objects b and c as below.

If the copying of other.b throws, then we are still in the original state so we can just let the exception escape. However, if that first copy succeeds, and then the copy of the RescourceManager2 object throws, then we are not in the original pre-copy state. Indeed, things are even worse than that, we cannot safely get back to the original state. Anything we do to try and restore the pre-copy state, would involve copying ResourceManager1 objects, which would potentially throw again.

So, instead, we are going to copy the ResourceManager2 object first. We are in luck here, because c is in fact a pointer, which is a primitive type, and, although copying the object it points to could throw, copying the pointer itself should not. This means that, we can split the operation into a copy that may throw but leaves our state unchanged, and an assignment that changes our state but should not throw. Concretely, we first copy the other.c object and store the result in a temporary pointer, and then separately assign value in that temporary point to c .

We do this copy of the underlying ResourceManager2 object first, if this throws, as we have not altered the state of the SafeCopyingClass object, we can let this exception escape. The assignment of the value in other.c to c , alters the state so it should go at the end, after all the code that may throw. So our copy constructor now looks like this:

Now we just have to deal with the copying of our ResourceManager1 object b . After creating the temporary pointer for our other.c but before we assign that pointer to c , we are still in the original state, so we can copy b and allow exceptions to escape, at this point, like so:

However, there is still one issue with our code. We have a potential resource leak, and that is not only bad practice, it is not exception safe. Suppose, when we copy the other.b object an exception is thrown. Then control will leave this copy constructor. However we created an object of type ResourceManager2 . The pointer temp_c is lost, but the object will live on, so we are leaking resources.

So, if the copy of other.b throws, we need to delete the object pointed to by temp_c . To do this, we wrap the ResourceManager1 copy in a try catch block. Then if an exception is thrown we can clean things up and rethrow the exception. So, here his our finished copy constructor:

What is the general strategy here? We split our copying into stuff that may throw and stuff that should not throw. We do everything that might throw before everything that will not throw. That makes any potential rollback a lot simpler. When we have a pointers, we should copy the underlying objects first and store the result in temporary pointers. After that, we do the rest of the potentially throwing copies, this is where we have to be aware of potential resource leaks and non trivial rollbacks.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

  • Windows Programming
  • UNIX/Linux Programming
  • General C++ Programming
  • Copy constructors, assignment operators,

  Copy constructors, assignment operators, and exception safe assignment

exception safe assignment

MyClass& other );
MyClass* other );
MyClass { x; c; std::string s; };
MyClass& other ) : x( other.x ), c( other.c ), s( other.s ) {}
, );
=( MyClass& rhs ) { x = other.x; c = other.c; s = other.s; * ; }
< T > MyArray { size_t numElements; T* pElements; : size_t count() { numElements; } MyArray& =( MyArray& rhs ); };
<> MyArray<T>:: =( MyArray& rhs ) { ( != &rhs ) { [] pElements; pElements = T[ rhs.numElements ]; ( size_t i = 0; i < rhs.numElements; ++i ) pElements[ i ] = rhs.pElements[ i ]; numElements = rhs.numElements; } * ; }
<> MyArray<T>:: =( MyArray& rhs ) { MyArray tmp( rhs ); std::swap( numElements, tmp.numElements ); std::swap( pElements, tmp.pElements ); * ; }
< T > swap( T& one, T& two ) { T tmp( one ); one = two; two = tmp; }
<> MyArray<T>:: =( MyArray rhs ) { std::swap( numElements, tmp.numElements ); std::swap( pElements, tmp.pElements ); * ; }
HOWEVER, if you have a type T for which the default std::swap() may result
in either T's copy constructor or assignment operator throwing, you are
politely required to provide a swap() overload for your type that does not
throw. [Since swap() cannot return failure, and you are not allowed to throw,
your swap() overload must always succeed.] By requiring that swap does not
throw, the above operator= is thus exception safe: either the object is
completely copied successfully, or the left-hand side is left unchanged.

exception safe assignment

Write clean and maintainable C++

exception safe assignment

Levels of Exception Safety

Exceptions are part of C++. They are thrown by the standard library classes, and sometimes even if we are not really using the standard library. So, unless we are in a very restrictive environment like embedded programming and have exceptions disabled in the compiler, we need to be prepared and deal with the fact that exceptions simply can happen.

The four levels

Any piece of code we write has one of four levels of exception safety: No guarantee, the basic guarantee, the strong guarantee anf the nothrow guarantee. Let’s consider them one by one.

What does it mean if code has no guarantee regarding exceptions? It simply means that if an exception is thrown during the execution of that piece of code, anything can happen. With “anything” I mean anything bad, from leaked resources to dangling pointers to violated class invariants. Here’s a very simple example:

At first glance this may look good, since the object passes both pointers straight to the two `unique_ptr`s that  take care of the memory release. But this code may leak memory, since when the second of the two `new`s fails, it will throw a `std::bad_alloc`. The exception will propagate out of the function while the memory allocated by the first `new` has not been given to a `unique_ptr` and therefore will never be freed.

Arguably, when the allocation of memory for something tiny like an `int` or `double` fails, we are in big trouble anyways, but the point is that this code may leak resources and is therefore not exception safe.

Generally, any code that has not been proven to be exception safe should has no guarantee and should be considered unsafe. Code without any exception guarantee is hard to work with – we can’t know for sure the state of the objects after an exception is thrown, which means that we possibly even can’t properly clean up and destroy them.

Don’t write code that has no exception guarantee.

Easier said than done? Not really, because the basic guarantee really is pretty basic. It says that if an exception is thrown during the execution of our code, no resources are leaked and we can be sure that our objects class invariants are not violated. Nothing more, nothing less.

It does especially mean that we don’t necessarily know the content or state or values of our objects, but we know we can use and destroy them, because the invariants are intact. That we can destroy them is probably the most important part of the basic guarantee, since a thrown exception will incur some stack unwinding and affected objects may get destroyed.

Design your classes to have proper class invariants that are always met, even in the presence of exceptions.

The strong guarantee adds to the basic guarantee, that if an operation fails with an exception, then it leaves the objects in the same state they had before. In general, for the strong guarantee we have to do all actions that could possibly throw without affecting any existing object, and then commit them with actions that are guaranteed to not throw an exception.

An example for the strong guarantee is the copy and swap idiom for assignment operators:

The steps are simple: first create a copy of the other object. This may throw an exception, but if it does, the function is terminated early and nothing has happened to `*this` or the other object yet. Then swap `*this` with the copy. For this to work, the swap operation may not throw any exceptions. Examples are the exchange of a few pointers and other built in types. The swap is the commit action, after that the assignment is complete. When the function is left with the return statement, the temporary object is destroyed, cleaning up the state previously owned by `*this`.

Providing the strong guarantee can be costly. For example, imagine if the `Strong` object in the example allocates large amounts of memory. Instead of reusing the already allocated memory, the temporary has to allocate new memory just to release the old one after the swap.

Provide the strong guarantee only if needed. Document operations that have the strong guarantee, use the basic guarantee as default.

The last missing level is the nothrow guarantee . It simply means that an operation can not throw an exception. As you have seen, nothrow operations are needed to provide the strong and basic guarantee. There are some operations that should never throw, no matter what:

  • destructors have to be nothrow, because they are called during stack unwinding. If an exception is active and a second exception is thrown during stack unwinding, the program will be terminated.
  • Any cleanup operations like closing files, releasing memory and anything else that might be called from a destructor should not throw.
  • swap operations. They are commonly expected not to throw. If you have an operation that exchanges the values of two objects but can’t provide the nothrow guarantee, don’t call it `swap` but something different like `exchange`.
Consider using the keyword `noexcept` to document operations that provide the nothrow guarantee.

Reasoning about exception safety can be hard, but thinking in the four levels no guarantee, basic guarantee, strong guarantee and nothrow guarantee makes it much easier. Have a short look at each function you write and make sure that it has at least the basic guarantee. If you use code you have not written, assume it has the basic guarantee as well unless it is documented otherwise.

16 Comments

' src=

In your particular example with list-initiliazation

DoubleOwnership object { new int(42), new double(3.14) };

it will work just fine, because there is a sequenced before relation in list-initialization.

(see here related discussion and quote from Standard http://stackoverflow.com/questions/14060264/order-of-evaluation-of-elements-in-list-initialization )

' src=

No, it won’t work just fine. Order of evaluation is not the issue here. The order of execution will basically be:

pre class=”lang:c++ decode:true”>int* tempPtr1 = new int(42); double* tempPtr2 = new double(3.14); //call constructor DoubleOwnership(tempPtr1, tempPtr2) //… etc The unique_ptr s will be constructed inside the DoubleOwnership constructor, i.e. after both new expressions have been evaluated . Now, if the new double(3.14) throws, e.g. because there is no more memory, there is no owner of the memory allocated by the first new . Therefore it creates a leak. See also Jens’ comment.

Oh, yeah, got it, sitting in the restroom! Thanks!

' src=

You’ve written a nice summary here.

BTW, your assignment operator can be tightened up a bit. Make the temporary copy by passing “other” by value:

Strong &amp; operator=(Strong other) { swap(other); return *this; }

(I suppose you might still want to say “other.swap(*this);”, to emphasize that you’re not calling a global swap function.)

The above is not only a bit more readable, it might also be a bit more efficient, as it is easier for a compiler to optimize.

' src=

I don’t understand why in the example, memory will be leaked. Doesn’t the first unique_ptr be destroyed?

Maybe I can understand it if you suggest a way to make it exception safe (with the same interface and the same main function).

' src=

Memory will be leaked because both “new” calls are evaluated before calling “DoubleOwnership” constructor. In that case if second new fails unique_ptr will not be created and we end up with allocated memory and no handle to it.

does the use of make_unique help? How would you make it safe? It looks like there is no way with the current interface. (I would make the argument unique_ptr in the first place)

Sadly, make_unique won’t help directly with this function signature, since it forces you to separate memory allocation (outside the function) and taking ownership (inside the function). The best way to make this safe is indeed to change the signature to expect two unique_ptr . A workaround would be to first allocate the memory safely and then pass it to the function in a second, nonthrowing step:

<pre class="lang:c++ decode:true">int foo() {

auto pi = make_unique(42); auto pd = make_unique(3.14); DoubleOwnership object { pi.release(), pd.release() }; //… }

' src=

Could explain why

int foo() { DoubleOwnership object { make_unique(42), make_unique(3.14) }; //… }

wouldn’t solve the problem? I think this first creates a temporary std::unique_ptr, and if the second constructor throws, the unique_ptr’s destructor will be called to release the memory (see also Herb Sutter’s GotW 102: http://herbsutter.com/gotw/_102/ ). The C++ Core Guidlines authors also think solves the problem:

fun(shared_ptr(new Widget(a, b)), shared_ptr(new Widget(c, d))); // BAD: potential leak

This is exception-unsafe because the compiler may reorder the two expressions building the function’s two arguments. In particular, the compiler can interleave execution of the two expressions: Memory allocation (by calling operator new) could be done first for both objects, followed by attempts to call the two Widget constructors. If one of the constructor calls throws an exception, then the other object’s memory will never be released!

This subtle problem has a simple solution: Never perform more than one explicit resource allocation in a single expression statement. For example:

shared_ptr sp1(new Widget(a, b)); // Better, but messy fun(sp1, new Widget(c, d));

The best solution is to avoid explicit allocation entirely use factory functions that return owning objects:

fun(make_shared(a, b), make_shared(c, d)); // Best

( https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#Rr-single-alloc )

The only problem I see is when DoubleOwnership’s constructor releases the pointer from one of the unique_ptrs, and then throws.

You first snippet would indeed be the best. However, it does not use the constructor taking two raw pointers. That is exactly the point I wanted to make: that constructor was difficult to use safely. I don’t see the problem you see with throwing after releasing: unique_ptr ‘s constructors and release operation are noexcept , so once the memory allocation has succeeded the DoubleOnwership construction will succeed as well.

' src=

Any cleanup operations like closing files, … that might be called from a destructor should not throw.

And so the error return code of the system is gone on closing generally. No, that’s the wrongest tip to say. If you need a nonthrowing close or destroy, write it and also a throwing one as the default version.

Usually there is no errors in closing something, especially since you normally neither expect nor are interested in whether shutting something went smoothly or not. So in most cases it is only natural to have a nonthrowing cleanup. In addition, if you can’t clean up something due to an error, what are you going to do? You will throw it away anyways. In addition, having two operations that do (mostly) the same thing, where one can throw and the other don’t, is a maintenance burden and a disaster waiting to happen. Someone will of course use the wrong version, causing an exception during stack unwinding. Debugging that kind of errors can be a real nightmare.

' src=

Usually there is no errors in closing something

Not? Most Windows-Functions for closing and destroying can return an error, on other systems too, I guess. Think of files on servers: Opening may be checked, writing is not checked because use of cache. So the only possible error return point is at closing the file. Real sample: Windows 95 did not check writing on floppy disc, it wrote all data at closing (unlike Windows NT 4, where ejecting and reinsert while writing was recoverable). std::uncaught_exceptions() may be useful for antis of 2 equal functions. Or catch(…) in destructor. Or making the non-throwing version protected or private. Or whatever. The point is: Most cleaning up operations must throw. Normally you have to cleanup manually, not per destructor — your second of the 3 points is incorrect formulated.

My point is exactly that you should normally not have to cleanup manually. Having to clean up is a responsibility that should be encapsuled in a RAII class . I am writing about very general guidelines here, so there naturally will be cases where those guidelines don’t fit. However, I don’t see how in the context of exceptions in modern C++, error codes in a 20 year old C library do make a good counter example.

' src=

Errors that occur during cleanup are rare, but they often indicate something catastrophic going on. The POSIX close() function is a great example showing two kinds of cleanup errors.

(1) Errors such as EIO, which may happen if, for example, a network error occurs when closing a file on an NFS mount. This error indicates your data isn’t saved and is a problem that should not be ignored—no different than a write() call that fails due to EIO.

(2) Errors such as EINVAL, which happen as a result of closing an invalid file descriptor. This indicates a dangling file descriptor in your program (i.e., a logic bug) or a corrupted file descriptor (i.e., who knows?). Again, neither error should be ignored. EINVAL indicates your program is in “undefined behavior” territory, and continuing as though nothing bad happened is a poor choice.

It’s exactly because cleanup errors are, as you say, “unusual,” that ignoring them is a bad idea. The common case is that no cleanup error occurs and your program runs okay. But when a cleanup error does occur, something catastrophic may be going on and it’s better to be alerted sooner rather than later. I prefer terminating. After all, a robust program recovers from a previous crash—even an unusual one. It’s the non-robust programs that can’t deal with crashing.

As far as I know, those POSIX functions are C functions which do not report errors by throwing exceptions. Cleanups that return error codes are acceptable – you can chose to ignore them or deal with the problem. However, cleanups that throw exceptions are a problem. You can hardly write RAII classes that use them, since if an exception is thrown from a destructor, be it during stack unwinding or during normal operation, terminate will be called since destructors are implicitly declared noexcept . And just crashing a program is a bad decision, because it means just ending the program without further notice and possibly losing more than just the data of that problematic file. Instead, raising all red flags you have and then gracefully shutting down the program is the better option. Note that I am not generally advocating against raising exceptions when a cleanup fails. I am advocating against the cleanup itself raising the exception. The difference is that during a normal function, you can check for cleanup success and in case of a problem throw (which may or may not lead to program shutdown), while in the destructor of the RAII class that manages the cleanup you don’t throw.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

exception safe assignment

  • Latest Articles
  • Top Articles
  • Posting/Update Guidelines
  • Article Help Forum

exception safe assignment

  • View Unanswered Questions
  • View All Questions
  • View C# questions
  • View C++ questions
  • View Javascript questions
  • View Visual Basic questions
  • View Python questions
  • CodeProject.AI Server
  • All Message Boards...
  • Running a Business
  • Sales / Marketing
  • Collaboration / Beta Testing
  • Work Issues
  • Design and Architecture
  • Artificial Intelligence
  • Internet of Things
  • ATL / WTL / STL
  • Managed C++/CLI
  • Objective-C and Swift
  • System Admin
  • Hosting and Servers
  • Linux Programming
  • .NET (Core and Framework)
  • Visual Basic
  • Web Development
  • Site Bugs / Suggestions
  • Spam and Abuse Watch
  • Competitions
  • The Insider Newsletter
  • The Daily Build Newsletter
  • Newsletter archive
  • CodeProject Stuff
  • Most Valuable Professionals
  • The Lounge  
  • The CodeProject Blog
  • Where I Am: Member Photos
  • The Insider News
  • The Weird & The Wonderful
  • What is 'CodeProject'?
  • General FAQ
  • Ask a Question
  • Bugs and Suggestions

exception safe assignment

Exception Safe Assignment

exception safe assignment

Longer title: exception safe assignment operator of resource owning objects . Uff. Because the object owns a resource, how do we write an exception safe assignment operator which will have to free up the old and allocate the new resource. By exception safe, I don’t mean that it will never throw, that’s not possible. Instead, I mean safe in the sense that it either succeeds OR in case of exceptions, the state of assigned to object is exactly as it was prior to the assignment. Like this:

If assignment operator...

...throws an exception, we want the state of...

...to be as it was in line #3 .

The trick is two fold:

  • a copy constructor is needed, and
  • noexcept swap function. Like this:

Here, the copy constructor allocates the new resource first, then copies its content; the swap function just swaps pointers to the resources, which is always a noexcept operation. Having implemented a copy constructor and swap function, we can now implement every assignment operator to have a strong exception guarantee like this:

Here’s how it works: we first make a temporary copy, which does the resource allocation. At this stage, exceptions can be thrown, but we have not yet modified the assigned to object. Only after the resource allocation succeeds do we perform the noexcept swap. The destructor of your temporary object will take care of cleaning up the currently owned resource (that’s RAII at its best).

Complete listing ( assignment.cpp ):

Program output:

This article, along with any associated source code and files, is licensed under The MIT License

exception safe assignment

Comments and Discussions

to use this message board.
  Layout   Per page    
First Prev Next
8-Apr-19 22:39 8-Apr-19 22:39 
What about COW copy on write?
·  
Last Visit: 31-Dec-99 18:00     Last Update: 29-Jun-24 3:32

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

exception safe assignment

FEATURES

  • Documentation
  • System Status

Resources

  • Rollbar Academy

Events

  • Software Development
  • Engineering Management
  • Platform/Ops
  • Customer Support
  • Software Agency

Use Cases

  • Low-Risk Release
  • Production Code Quality
  • DevOps Bridge
  • Effective Testing & QA

What is “except Exception as e” in Python?

What is “except Exception as e” in Python?

Table of Contents

except Exception as e is a construct in Python used for exception handling. It allows you to catch exceptions that occur during the execution of a block of code by using a try block to wrap the code that might raise an exception, and an except block to catch and handle the exception.

The Exception part specifies that any exception of this type or its subclasses should be caught, and the as e part assigns the caught exception to a variable e , which you can then use to access details about the exception.

Take a look at this example:

Running that will print:

This is what happens step-by-step:

  • The try block attempts to execute result = 10 / 0 .
  • Division by zero is not allowed so a ZeroDivisionError is raised.
  • The except Exception as e block catches the ZeroDivisionError .
  • The exception is assigned to the variable e , which contains the error message "division by zero".
  • The print(f"An error occurred: {e}") statement prints the error message to the console.

When using except Exception as e , here are a few things to keep in mind for handling exceptions effectively:

Catch specific exceptions rather than all exceptions

Catching all exceptions with except Exception as e can mask unexpected errors and make debugging more difficult.

💡Best Practice: Whenever possible, catch specific exceptions (e.g., except ZeroDivisionError as e ) to handle different error conditions appropriately.

Clean up resources

Ensure that resources (e.g., files or network connections) are properly released even if an exception occurs.

💡Best Practice: Use a finally block to clean up resources. Like this:

Use chained exceptions to catch one exception and raise another

Chained exceptions allow you to catch one exception and raise another while preserving the original exception's context. This is helpful for debugging because it provides a clear trail of what went wrong.

💡Best Practice: Each function should handle its own specific concerns but communicate issues up the call stack with chained exceptions.

Imagine a scenario where you have a function that validates user input and another function that processes that input. If the input is invalid, the validation function raises a specific error, and the processing function raises a more general error to be handled higher up in the call stack.

When you run that code, the output will be:

The main function catches the ValueError raised by process_input and prints both the general error message and the original exception.

Log exceptions

Logging exceptions helps with debugging and maintaining a record of errors.

💡Best Practice: Use the exception monitoring SDK Rollbar which gives you a real-time feed of all errors, including unhandled exceptions. Rollbar's revolutionary grouping engine uses machine learning to determine patterns on an ongoing basis and identify unique errors.

When you run this code, any exceptions caught in the except block will be logged to Rollbar, allowing you to find and fix errors in your code faster. Try Rollbar today !

Related Resources

How to catch multiple exceptions in Python

How to Catch Multiple Exceptions in Python

How to Fix “IndexError: List Assignment Index Out of Range” in Python

How to Fix “IndexError: List Assignment Index Out of Range” in Python

How to Fix Invalid SyntaxError in Python

How to Fix Invalid SyntaxError in Python

"Rollbar allows us to go from alerting to impact analysis and resolution in a matter of minutes. Without it we would be flying blind."

Error Monitoring

Start continuously improving your code today.

exception safe assignment

Special Features

Vendor voice.

exception safe assignment

Microsoft hits snooze again on security certificate renewal

Seeing weird warnings in microsoft 365 and office online that'll be why.

Microsoft has expiration issues with its TLS certificates, resulting in unwanted security warnings.

An eagle-eyed Register reader from Australia brought the plight of cdn.uci.officeapps.live.com to our attention, which is listed at one of Microsoft's worldwide endpoints for Microsoft 365 and Office Online. According to Microsoft, the address is default and requires network connectivity.

TLS Certificate information on cdn.uci.officeapps.live.com

TLS Certificate information on cdn.uci.officeapps.live.com

Our reader realized the situation when some security software began to bleat about the connection not being secure when using Microsoft Office.

A Transport Level Security (TLS) certificate is commonly used to secure internet connections with data encryption. According to DigiCert: "They ensure that data is transmitted privately and without modifications, loss or theft." Assuming, of course, the certificate is valid.

In the case of cdn.uci.officeapps.live.com , it was valid from August 18, 2023, to June 27, 2024, and despite appearing in the list of Microsoft's worldwide endpoints has now expired. The result will be headaches for administrators dealing with strange security errors popping up on some users' screens and somebody within Microsoft doubtless being given a stern talking to.

The warning also noted that Microsoft Azure ECC TLS Issuing CA 01 has expired, which could spell problems for certificates issued by the service. The situation has not gone unnoticed on Microsoft's own support forums , with one poster saying: "We have 200 PCs now giving this code when opening Word."

Windows: Insecure by design

'skeleton key' attack unlocks the worst of ai, says microsoft, microsoft yanks windows 11 update after boot loop blunder, how many microsoft missteps were forks that were just a bit of fun.

Microsoft is no stranger to expiration whoopsies. In 2022, it forgot to renew the certificate for the web page of its Windows Insider subdomain, resulting in security warnings for its army of unpaid testers when they attempted to access the site.

The Register contacted Microsoft for comment and will update this piece should the company have anything to share. Microsoft previously announced plans to tackle its URL sprawl with a shift to cloud.microsoft.

exception safe assignment

Of the expiration, our reader mused: "I seem to remember this happening on many occasions in the past. It seems a bit strange that expiry dates for strategic systems such as website security certificates are not kept as a list in, say, a commonly used spreadsheet."

If only Microsoft had access to something that could store and sort data in such a way.

We asked Microsoft Copilot how to handle the expiration of TLS certificates. It suggested monitoring expiration dates and renewing certificates before they expire.

It ended with a chirpy: "Remember, expired certificates can lead to service outages and unencrypted connections, affecting your organization's reputation and customer relationships. Stay vigilant and keep those certificates up-to-date! 😊" ®

  • Digital certificate

Narrower topics

  • Active Directory
  • Exchange Server
  • Internet Explorer
  • Microsoft 365
  • Microsoft Build
  • Microsoft Edge
  • Microsoft Ignite
  • Microsoft Office
  • Microsoft Surface
  • Microsoft Teams
  • Patch Tuesday
  • Visual Studio
  • Visual Studio Code
  • Windows Server
  • Windows Server 2003
  • Windows Server 2008
  • Windows Server 2012
  • Windows Server 2013
  • Windows Server 2016
  • Windows Subsystem for Linux

Broader topics

Send us news

Other stories you might like

Microsoft answered congress' questions on security. now the white house needs to act, eu accuses microsoft of antitrust violations for bundling teams with o365, unleashing the power and control of industry-specific cloud platforms.

exception safe assignment

Antitrust latest: Europe's Vestager warns Microsoft, OpenAI 'the story is not over'

Microsoft blamed for million-plus patient record theft at us hospital giant, microsoft's latest surface devices almost as easy to fix as they are to break, microsoft's new surface laptop 7 has arrived. the recovery images have not, microsoft ceo of ai: your online content is 'freeware' fodder for training models.

icon

  • Advertise with us

Our Websites

  • The Next Platform
  • Blocks and Files

Your Privacy

  • Cookies Policy
  • Privacy Policy
  • Ts & Cs

Situation Publishing

Copyright. All rights reserved © 1998–2024

no-js

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Are compiler-generated assignment operators unsafe?

It was my understanding that the C++ compiler generates assignment operators like this:

Isn't this exception-unsafe? If member2 = other.member2 throws, then the original assignment's side effects are not undone.

Puppy's user avatar

  • It doesn't provide the strong exception guarantee. That's not the same thing as not begin safe. There will be no memory leaks or anything like that. –  Benjamin Lindley Commented Jun 3, 2014 at 14:59
  • @BenjaminLindley: I think that not providing the strong guarantee is inherently unsafe, in general, and certainly should merit special consideration from the programmer where non-strong functions are concerned. –  Puppy Commented Jun 3, 2014 at 15:00
  • Hmm... what are the guarantees from the standard concerning partial assignment? –  Mgetz Commented Jun 3, 2014 at 15:06
  • @DeadMG: Then you have your answer, no? But you should probably clarify in your question exactly what "exception-unsafe" means to you. –  Benjamin Lindley Commented Jun 3, 2014 at 15:08
  • 4 I'm not sure what the question is here. Is it "are assignment operators generated like this?", or is it "I know assignment operators are generated like this; does this allow an exception to leave an object half-assigned?", or is it "I know assignment operators are generated like this, and that this allows an exception to leave an object half-assigned; is that considered exception-unsafe?" –  user743382 Commented Jun 3, 2014 at 15:11

2 Answers 2

Using the 4 level exception safety system:

  • Strong Guarantee -- operation completes, or is rolled back completely
  • Basic Guarantee -- invariants are preserved, no resources leaked
  • No Guarantees

The compiler generated assignment operator has the basic exception guarantee if each of the members of the object provides the basic exception guarantee or "better", and if the objects invariants do not have intra-member dependencies.

It has the no throw guarantee if each member's assignment also has the no throw guarantee.

It rarely (if ever) has the strong guarantee, which is possibly what you are referring to as "exception unsafe".

The copy-swap idiom is popular because writing no-throw swap is often easy, and constructors should already provide the strong exception guarantee. The result is an operator= with the strong exception guarantee. (In the case of move , it is pseudo-strong, as the input is often not rolled back, but it is an rvalue)

If you also take the copy by-value, you can sometimes upgrade operator= to being no throw (with the only exception being possibly in the construction of the argument).

in some cases, some constructors of Foo are noexcept and others are not: by taking the other by-value, we provide the best exception guarantee we can in total (as the argument to = can sometimes be directly constructed, either by elision or direct construction via {} ).

It is not practical for the language (at least at this time) to implement a copy-swap operator= with the strong guarantee for a few reasons. First, C++ operates on "you only pay for what you use", and copy-swap can be more expensive than memberwise copy. Second, swap is not currently part of the core language (there are some proposals to add operator :=: and fold it in). Third, reverse compatibility with previous versions of C++ and with C.

Yakk - Adam Nevraumont's user avatar

Edited 4 June 2014

My initial answer was based on my understanding that the original poster sought an assignment operator guaranteed not to throw an exception. As per various commenters, it has become apparent that exceptions are OK as long as the object is left un-altered on an exception.

The suggested way to do this is via temp variables and std::swap().

In fact we cannot rely that swap() won't throw an exception, unless we know a bit about the components of our object.

To be sure that swap() will never throw, we need the member objects to be Move Assignable and Move Constructible .

In the example given, with a C++11 or later compiler the std::vector<int> is move assignable and move constructible, so we are safe. However as a general solution we always need to be aware of any assumptions we are making and to check that they are holding.

Michael J's user avatar

  • 1 I would expect it to not catch the exception, but rather copy 1 to 2 temps, if that works then swap them (which won't throw). If the copying throws the object is left unchanged. –  paulm Commented Jun 3, 2014 at 15:19
  • If the members are POD (plain old data) then no exception will be thrown and everything is safe. If the members can throw exceptions, then that means that the assignment can fail. Even if you mess 'round with temps and swap() you might still fail. What do you do then? –  Michael J Commented Jun 3, 2014 at 15:24
  • 1 @MichaelJ If you use temporaries, and it fails during the construction of the temporary, your own instance won't have been modified yet. So, you do nothing. The caller can catch the exception if appropriate, or not. Either way, it's not your problem. If it fails during the swap between your own instance and that temporary, you've got a poorly-defined swap, because that should pretty much never need to throw, and in that case, fix the swap function. –  user743382 Commented Jun 3, 2014 at 15:26
  • swap from the temps should never throw, or fail! It should boil down to re-assigning pointers –  paulm Commented Jun 3, 2014 at 15:43
  • 2 Your answer seems to be guided by the idea that the goal is for the assignment operator to not throw exceptions. But that is not the point. Your solution (which is a terrible idea, imo) doesn't even guarantee that anyway, since exceptions do not necessarily derive from std::exception (though they should). The goal is that if an exception is thrown, it is guaranteed that the object is left unmodified. –  Benjamin Lindley Commented Jun 3, 2014 at 15:58

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c++ or ask your own question .

  • Featured on Meta
  • Upcoming sign-up experiments related to tags
  • Should we burninate the [lib] tag?
  • Policy: Generative AI (e.g., ChatGPT) is banned
  • What makes a homepage useful for logged-in users

Hot Network Questions

  • Tubeless tape width?
  • How to produce this table: Probability datatable with multirow
  • Clip data in GeoPandas to keep everything not in polygons
  • Less ridiculous way to prove that an Ascii character compares equal with itself in Coq
  • Can I tell a MILP solver to prefer solutions with fewer fractions?
  • adding *any* directive above Include negates HostName inside that included file
  • Fantasy TV series with a male protagonist who uses a bow and arrows and has a hawk/falcon/eagle type bird companion
  • How do guitarists remember what note each string represents when fretting?
  • Issue with rendering Lightning progress indicator
  • Is there any legal justification for content on the web without an explicit licence being freeware?
  • Do countries at war always treat each other's diplomats as personae non gratae?
  • Why was the animal "Wolf" used in the title "The Wolf of Wall Street (2013)"?
  • What to do if you disagree with a juror during master's thesis defense?
  • Should I accept an offer of being a teacher assistant without pay?
  • How can I confirm for sure that a CVE has been mitigated on a RHEL system?
  • Font shape warnings in LuaLaTeX but not XeLaTeX
  • Visit USA via land border for French citizen
  • Weird behavior by car insurance - is this legit?
  • How will the ISS be decommissioned?
  • Synthesis of racemic nicotine
  • A chess engine in Java: generating white pawn moves
  • Is there a way to non-destructively test whether an Ethernet cable is pure copper or copper-clad aluminum (CCA)?
  • What is the translation of misgendering in French?
  • Diagnosing tripped breaker on the dishwasher circuit?

exception safe assignment

IMAGES

  1. Array : Exception safety in array assignment using postincremented

    exception safe assignment

  2. PPT

    exception safe assignment

  3. (Solved) : Assignment Week Make Fractiontype Class Safe Using Exception

    exception safe assignment

  4. Exceptions 2 CMSC ppt download

    exception safe assignment

  5. Oop Assignment (Exception Handling)

    exception safe assignment

  6. Exceptions 2 CMSC ppt download

    exception safe assignment

VIDEO

  1. Residence Management (Video Presentation)

  2. Modes of Charging Security

COMMENTS

  1. c++

    Thus, the above approach implements the strong exception guarantee. Interestingly, the copy assignment needs to do a self-assignment check to prevent locking the same mutex twice. Normally, I maintain that a necessary self-assignment check is an indication that the assignment operator isn't exception safe but I think the code above is exception ...

  2. C++ Exception-Safe Assignment Overloading

    Exception-Safe and Self-Assignment. Make sure the resource management inside the assignment overloading has taken throwing exceptions into account to prevent the data loss from the object. In the following example, we strictly follow allocate, populate and deallocate. If we deallocate the cstringmember variable before allocate the new buffer ...

  3. Exception safe assignment

    Exception safe assignment. Longer title: exception safe assignment operator of resource owning objects. Uff. Because the object owns a resource, how do we write an exception safe assignment operator which will have to free up the old and allocate the new resource. By exception safe I don't mean that it will never throw, that's not possible.

  4. Do you (really) write exception safe code?

    Writing exception safe code. To write exception safe code, you must know first what level of exception safety each instruction you write is. For example, a new can throw an exception, but assigning a built-in (e.g. an int, or a pointer) won't fail. A swap will never fail (don't ever write a throwing swap), a std::list::push_back can throw...

  5. PDF Appendix

    Standard-Library Exception Safety Everything will work just as you expect it to, unless your expectations are incorrect. - Hyman Rosen Exception safety — exception-safe implementation techniques — representing resources — assignment —p pu us sh h_ _b ba ac ck k()— constructors and invariants — standard container

  6. PDF Exception Safety: Concepts and Techniques

    user-supplied operations (such as assignments ands sw wa ap p()functions) do not leave container elements in invalid states, that user-supplied operations do not leak ... In addition to achieving pure exception safety, both the basic guarantee and the strong guarantee ensure the absence of resource leaks. That is, a standard library oper- ...

  7. How to: Design for exception safety

    To be exception-safe, a function must ensure that objects that it has allocated by using malloc or new are destroyed, and all resources such as file handles are closed or released even if an exception is thrown. The Resource Acquisition Is Initialization (RAII) idiom ties management of such resources to the lifespan of automatic variables. When ...

  8. Copy constructors, assignment operators,

    search for a handler. If an exception is thrown while unwinding the stack, the program necessarily and unstoppably terminates. How do I write an exception safe assignment operator? The recommended way to write an exception safe assignment operator is via the copy-swap idiom. What is the copy-swap idiom? Simply put, it is a two-

  9. Exception Handling in C++: Exception safety

    Exception-safe code leaves objects in a consistent state and does not leak resources. You also need to be careful writing custom assignment operators. In Chapter 12 of Volume 1, you saw that operator= should adhere to the following pattern: Make sure you're not assigning to self. If you are, go to step 6.

  10. GotW #59: Exception-Safe Class Design, Part 1: Copy Assignment

    GotW #59: Exception-Safe Class Design, Part 1: Copy Assignment. This is the original GotW problem and solution substantially as posted to Usenet. See the book More Exceptional C++ (Addison-Wesley, 2002) for the most current solution to this GotW issue. The solutions in the book have been revised and expanded since their initial appearance in GotW.

  11. 22. Exception-Safe Class Design, Part 1: Copy Assignment

    Chapter 22. Exception-Safe Class Design, Part 1: Copy Assignment Difficulty: 7 Is it possible to make any C++ class strongly exception-safe, for example, for its copy assignment operator? If so, … - Selection from More Exceptional C++ [Book]

  12. More C++ Idioms/Copy-and-swap

    Exception safety is a very important cornerstone of highly reliable C++ software that uses exceptions to indicate "exceptional" conditions. There are at least 3 types of exception safety levels: basic, strong, and no-throw. ... In C++11, such an assignment operator is known as a unifying assignment operator because it eliminates the need to ...

  13. Exception safety: The strong guarantee and move semantics

    Exception safe code and move semantics. I want to write container class. This container has insert method that have two specializations - first uses copy constructors to copy data from one container to another container element wise. If copy constructor throws exception I just undo all changes to the container like nothing happens.

  14. campjake/Exception-Safe-Stack

    Implementing an exception safe and exception neutral stack, from Tom Cargill's 1994 Article "Exception Handling: A False Sense of Security" in the C++ Report - campjake/Exception-Safe-Stack. ... This wasn't that different from a normal homework assignment on writing a stack class, but the perspective shift to focus on exception safety still ...

  15. Staying Safe in C++

    The assignment of the value in other.c to c, alters the state so it should go at the end, after all the code that may throw. So our copy constructor now looks like this: SafeCopyingClass(const SafeCopyingClass& other) {. ResourceManager2* temp_c = new ResourceManager2(*other.c); // more copying logic that might throw. c = temp_c;

  16. Copy constructors, assignment operators,

    Foo's copy constructor or assignment operator can throw for any reason, then the default std::swap() shown above is not exception safe for Foo, and thus to be exception safe, you need to make an overload of std::swap for Foo that guarantees not to throw (or fail). As to how to go about doing that depends upon what Foo has in it.

  17. Levels of Exception Safety

    Reasoning about exception safety can be hard, but thinking in the four levels no guarantee, basic guarantee, strong guarantee and nothrow guarantee makes it much easier. ... BTW, your assignment operator can be tightened up a bit. Make the temporary copy by passing "other" by value: Strong & operator=(Strong other) {swap(other);

  18. Exception Safe Assignment

    Longer title: exception safe assignment operator of resource owning objects. Uff. Because the object owns a resource, how do we write an exception safe assignment operator which will have to free up the old and allocate the new resource. By exception safe, I don't mean that it will never throw, that's not possible.

  19. c++

    I generally (try to) write exception safe copy assignment operators using the copy-swap idiom, and I was wondering if I should be concerned about exceptions when writing the move assignement operators. Here is an example of a copy assignement operator: template<class T>. CLArray<T>&. CLArray<T>::operator=( const CLArray& rhs )

  20. What is "except Exception as e" in Python?

    except Exception as e is a construct in Python used for exception handling. It allows you to catch exceptions that occur during the execution of a block of code by using a try block to wrap the code that might raise an exception, and an except block to catch and handle the exception.. The Exception part specifies that any exception of this type or its subclasses should be caught, and the as e ...

  21. Microsoft hits snooze again on security certificate renewal

    Microsoft has expiration issues with its TLS certificates, resulting in unwanted security warnings. An eagle-eyed Register reader from Australia brought the plight of cdn.uci.officeapps.live.com to our attention, which is listed at one of Microsoft's worldwide endpoints for Microsoft 365 and Office Online. According to Microsoft, the address is default and requires network connectivity.

  22. c++ assignment operator exception safety

    1. A possible reason for wanting assignment operators to not throw is that the nothrow-ness of the constructors and assignment operators "leaks" up to a container that contains those objects. There is a type trait is_nothrow_move_assignable which is apparently desirable to have. - M.M.

  23. Are compiler-generated assignment operators unsafe?

    8. Using the 4 level exception safety system: The compiler generated assignment operator has the basic exception guarantee if each of the members of the object provides the basic exception guarantee or "better", and if the objects invariants do not have intra-member dependencies. It has the no throw guarantee if each member's assignment also ...