473,507 Members | 2,375 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Swap function

Does anyone know if an analogue to the "swap()" function found in C++ exists
in C#. For those not familiar, let's say you have a function that loads some
collection passed in by reference. If an error occurs while loading then the
collection will be in an indeterminate state. The work-around in C++ is to
load a temporary collection first and once successful, invoke a (native)
"swap()" function to exchange each object's internal "handle" to the
collection (fast, efficient, and error-free). Before I start rolling my own,
does anything like this already exist (natively) in C# (or what's the
generally accepted equivalent if any). Thanks.
Jan 15 '07 #1
6 11576
Hi

No, AFAIK there is nothing like that in .NET, could you be a little more
explanative regarding what you are loading, etc?
As I said this is the first time ever that I see mentioned something like
this.
--
Ignacio Machin
machin AT laceupsolutions com
"Jack White" <no_spam@_nospam.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
| Does anyone know if an analogue to the "swap()" function found in C++
exists
| in C#. For those not familiar, let's say you have a function that loads
some
| collection passed in by reference. If an error occurs while loading then
the
| collection will be in an indeterminate state. The work-around in C++ is to
| load a temporary collection first and once successful, invoke a (native)
| "swap()" function to exchange each object's internal "handle" to the
| collection (fast, efficient, and error-free). Before I start rolling my
own,
| does anything like this already exist (natively) in C# (or what's the
| generally accepted equivalent if any). Thanks.
|
|
Jan 15 '07 #2
Jack White wrote:
Does anyone know if an analogue to the "swap()" function found in C++ exists
in C#. For those not familiar, let's say you have a function that loads some
collection passed in by reference. If an error occurs while loading then the
collection will be in an indeterminate state. The work-around in C++ is to
load a temporary collection first and once successful, invoke a (native)
"swap()" function to exchange each object's internal "handle" to the
collection (fast, efficient, and error-free). Before I start rolling my own,
does anything like this already exist (natively) in C# (or what's the
generally accepted equivalent if any). Thanks.
If you pass the argument by ref you can do that in C#.

Arne
Jan 15 '07 #3
No, AFAIK there is nothing like that in .NET, could you be a little more
explanative regarding what you are loading, etc?
For the moment I'm just wondering about the situation in general. How would
you handle the example I cited for instance. The C++ standard documents
exception safety rules which aren't as much of an issue in C# but still
present to some extent. There are three fundamental rules known as the
"basic", "strong" and "nothrow" guarantees which is what I'm really asking
about. You can read about these on the web (or see here for Stroustrup's own
treatise on the subject: http://www.research.att.com/~bs/3rd_safe.pdf) but
I'm really interested in how C# deals with these issues. Any insight you can
provide would be welcome. Thanks.
Jan 15 '07 #4
Jack White wrote:
Does anyone know if an analogue to the "swap()" function found in C++ exists
in C#. For those not familiar, let's say you have a function that loads some
collection passed in by reference. If an error occurs while loading then the
collection will be in an indeterminate state. The work-around in C++ is to
load a temporary collection first and once successful, invoke a (native)
"swap()" function to exchange each object's internal "handle" to the
collection (fast, efficient, and error-free). Before I start rolling my own,
does anything like this already exist (natively) in C# (or what's the
generally accepted equivalent if any). Thanks.
In C++ this is required due to risks of exceptions in copy constructors,
no? AFAIK it's down to exception safety in value-oriented types. It's
especially pernicious because of STL value-oriented containers, and the
risks of exceptions while adding value-types with copy constructors,
assignment operators etc.

The normal practice in C# would be to either (1) return a new collection
rather than filling a passed-in collection (this is the far more common
method), or (2) undo changes in an except block. E.g.:

---8<---
void FillInStuff<T>(List<Tstuff)
{
List<Tsaved = new List<T>(stuff);
try
{
// risky operation
}
except
{
stuff.Clear();
stuff.AddRange(saved);
throw; // rethrow exception
}
}
--->8---
-- Barry

--
http://barrkel.blogspot.com/
Jan 16 '07 #5
In C++ this is required due to risks of exceptions in copy constructors,
no?
Copy constructors are only one aspect of it.
AFAIK it's down to exception safety in value-oriented types.
It's especially pernicious because of STL value-oriented containers, and
the
risks of exceptions while adding value-types with copy constructors,
assignment operators etc.

The normal practice in C# would be to either (1) return a new collection
rather than filling a passed-in collection (this is the far more common
method), or (2) undo changes in an except block. E.g.:

---8<---
void FillInStuff<T>(List<Tstuff)
{
List<Tsaved = new List<T>(stuff);
try
{
// risky operation
}
except
{
stuff.Clear();
stuff.AddRange(saved);
throw; // rethrow exception
}
}
The issues run much deeper. First, what exception guarantees do the native
..NET types make, let alone user-defined types (also considering their impact
on exception safety when interacting with the native .NET types). Can I
safely assume for instance that anytime I call a member function on any
native .NET object, my object will remain completely unaltered if an
exception is thrown (the "strong guarantee")? Or does it only support the
"basic guarantee" for instance, where the object's invariants are maintained
so I can recover (the object isn't corrupted), but the state of the object
is otherwise unknown (maybe I only have to reset the cursor in some stream
object for instance). Your own example provides a simple demonstration of
this situation. First, it's inefficient. You construct a backup copy first
when it would be much faster to simply build your new copy as a temporary
and reassign it to the original in an exception-safe way (normally by
exchanging the references but that requires passing it in by reference -
note that C++ can do it this way as well or otherwise rely on a "swap()"
function which simply and safely exchanges each object's internal "handle"
to the data). Even rolling it back requires yet more copying . What if
failure occurs however at any given time during the call to "Clear()" or
"AddRange()". What is the state of "stuff" at this point. Well, it's already
lost its existing data in the "try" block itself (a no-no) but more to the
point, what if "AddRange()" throws for example. Is "stuff" even in a valid
(uncorrupted) state. I assume the C# language says yes (providing the "basic
guarantee") but even so, is "stuff" itself now partially-filled with data or
does it remain completely intact (clear because of your previous call but
even without clearing it first, what's the state of data you copied into it
in the "try" block). Moreover, rolling back changes after an error may not
always be practical, efficient, possible, or exception safe itself. The C++
committee spent years hashing these issues out and C# probably adopted many
of their decisions but I'd like to see some white-paper on the subject in
the context of C# itself (whose issues aren't as complex as C++ but exist
nevertheless).
Jan 17 '07 #6
Jack White wrote:
The issues run much deeper.
Yes, I'm well aware of some of the hair-splitting debates on this in the
C++ community. I still stand by my position though, that the worst of it
is caused by the ability of the user to inject exceptions into
operations that could never throw in a language like C#, such as
assignments, parameter passing, return values, etc.

Simple example: it's impossible to write an exception-safe mutator
template method that returns a value of a user-defined type in C++, as
you know. std::stack<T>::pop() doesn't return the value popped for
precisely this reason.
First, what exception guarantees do the native
.NET types make
You'll need to read the documentation to get this, but usually time with
..NET Reflector is needed to get full information. Note that out of
memory and stack overflow can occur at almost any time, and will result
in the app domain being torn down. This puts a hard limit on how
resilient an individual app domain can be, so you may want (need) to
lower your ambitions in this area.
Can I
safely assume for instance that anytime I call a member function on any
native .NET object, my object will remain completely unaltered if an
exception is thrown (the "strong guarantee")? Or does it only support the
"basic guarantee" for instance, where the object's invariants are maintained
so I can recover (the object isn't corrupted), but the state of the object
is otherwise unknown (maybe I only have to reset the cursor in some stream
object for instance).
This isn't a scientific statement, but a well-written class ought to
hold the strong guarantee for unitary operations (e.g. List<T>.Add), and
hold the basic guarantee for aggregate operations (e.g.
List<T>.AddRange) (but note below that it doesn't). One hopes that the
..NET classes in question are well written, and mostly they are. There
are some dodgy ones in there too, unfortunately (though most of the
crimes are in API design, not implementation).
Your own example provides a simple demonstration of
this situation. First, it's inefficient.
Efficiency is more important than correctness? If your concern is about
strong exception safety, I'd relegate efficiency to the bottom of your
list, because strong exception safety usually implies transactions,
which are (almost) never free.
You construct a backup copy first
when it would be much faster to simply build your new copy as a temporary
and reassign it to the original in an exception-safe way (normally by
exchanging the references but that requires passing it in by reference -
note that C++ can do it this way as well
C# can do this also, via 'ref', which passes in the reference to the
list by reference rather than by value. However, this is rare because it
forces the caller to control all the existing references to that list
instance on the heap and update them with the new reference value it
receives from calling the method. That's why I didn't write the method
that way.
or otherwise rely on a "swap()"
function which simply and safely exchanges each object's internal "handle"
to the data).
If you want to do this, you can't use the .NET collection classes.
You're free to write your own classes to do this of course.
Even rolling it back requires yet more copying .
Yep. Strong exception safety for aggregate operations basically amounts
to starting a transaction and rolling it back. The 'copy the world, copy
back if error' is one of the shortest (in code space) ways of doing
that, which is all I was after (also, not knowing what was happening in
the body of the try..except).
What if
failure occurs however at any given time during the call to "Clear()"
The List<T>.Clear() operation won't fail, but you'll have to take my
word for that! It clears the internal array, and sets an index, but it
doesn't do anything that would throw an exception (except stack
overflow, which you can't do much about, as indicated earlier).
or
"AddRange()".
AddRange() could throw OutOfMemoryException or StackOverflow when
creating the iterator, but again, you can't control that. If one were
passing an arbitrary collection to AddRange(), and threw an exception in
ICollection<T>.CopyTo(), then one could really mess up the list (so
List<T>.AddRange() provides neither exception guarantee). That won't
happen with List<T>.CopyTo() though, because it boils down to
Array.Copy, which shouldn't have any problems (though it specifically
doesn't give guarantees, i.e. it may corrupt the array if it e.g. can't
cast an instance when copying from one array to another).
What is the state of "stuff" at this point.
It's pretty irrelevant, since the application is terminating if either
of the above two exceptions are thrown.
Well, it's already
lost its existing data in the "try" block itself (a no-no)
I don't understand what you mean by this. "stuff" is restored by the
except block, and the only things that can stop that are fatal errors,
due to generics being used in the example (so e.g. Array.Copy can't fail
due to typecasting etc.).
but more to the
point, what if "AddRange()" throws for example. Is "stuff" even in a valid
(uncorrupted) state.
In the most general sense, for any AddRange() call, no, it may be
corrupted.
I assume the C# language
The C# language doesn't much to say in this specific matter. It's down
to how the .NET library classes themselves are written, which is more
part of the CLI specification than C#.
says yes (providing the "basic
guarantee") but even so, is "stuff" itself now partially-filled with data or
does it remain completely intact
No, data may be shifted up, items may be lost, etc.
(clear because of your previous call but
even without clearing it first, what's the state of data you copied into it
in the "try" block).
Exception safety is a recursive concept; the try block in my example is
empty, but of course for the whole thing to be exception safe, the
operations inside must also be exception safe, possibly requiring extra
exception handlers etc.
Moreover, rolling back changes after an error may not
always be practical, efficient, possible,
It always amuses me when C++ programmers put "efficient" ahead of things
like correctness, or even "possible" ;-)
or exception safe itself.
Of course; that's why basic exception guarantees are more usual for
aggregate operations.
The C++
committee spent years hashing these issues out
And I stand by what I said at the start. Another reason why it's so bad
in C++ is lack of GC and stronger guarantees on e.g. bounds-checked
arrays. Exception safety is usually required to ensure that all memory
is freed up, and to avoid writing past the ends of arrays, etc.
and C# probably adopted many
of their decisions
Largely, no, not in this area, I don't think so.
but I'd like to see some white-paper on the subject in
the context of C# itself (whose issues aren't as complex as C++ but exist
nevertheless).
I think that would be good too, beyond what's covered by the reliability
contract and constrained execution region stuff. The approach in .NET is
much more a "best-effort" setup, yet bounded by the app domain, rather
than giving hard guarantees on the framework classes.

-- Barry

--
http://barrkel.blogspot.com/
Jan 19 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
10010
by: Steve Hill | last post by:
Hi, suppose I have a vector allocated on the heap. Can I use a temporary (stack based vector) and swap to clear it, or is this unsafe. e.g. vector<int> *v; vector<int> tmp; v->swap(tmp); // is...
2
1973
by: ma740988 | last post by:
So I'm reading the C++ coding standards(Shutter & Andrei), more specifically item 56. There's a statement: "Prefer to provide a nonmember swap function in the same namespace as your type when...
7
1708
by: Kai-Uwe Bux | last post by:
Hi folks, I am still struggling with the rules for name lookup. Please consider: namespace xxx {
12
15068
by: Eugen J. Sobchenko | last post by:
Hi! I'm writing function which swaps two arbitrary elements of double-linked list. References to the next element of list must be unique or NULL (even during swap procedure), the same condition...
4
4088
by: Niels Dekker (no reply address) | last post by:
When calling swap as follows (as recommanded in Effective C++, 3rd Edition, by Scott Meyers), what swap is chosen to be called? using std::swap; swap(a, b); Suppose there is a global ::swap...
9
6173
by: ma740988 | last post by:
Consider: # include <vector> # include <iostream> # include <cstdlib> # include <ctime> bool ispow2i ( double n ) {
3
1646
by: Narmada Padhy | last post by:
1> #include<iostream> using namespace std; void swap(int& i, int& j) { int tmp = i; i = j; j = tmp; cout<<"The value after swap of x and y is"<<i<<" "<<j<<endl;
28
2817
by: Jess | last post by:
Hello, It is said that if I implement a "swap" member function, then it should never throw any exception. However, if I implement "swap" non- member function, then the restriction doesn't...
4
3268
by: George2 | last post by:
Hello everyone, The following swap technique is used to make assignment operator exception safe (means even if there is exception, the current object instance's state is invariant). It used...
11
2904
by: Dennis Jones | last post by:
Hi all, 1) Let's say you have two char 's of the same size. How would you write a no-fail swap method for them? For example: class Test { char s; void swap( Test &rhs ) {
0
7223
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7376
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7031
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
5042
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4702
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3191
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3179
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
760
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
412
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.