Topic: swap byte by byte
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/10/11 Raw View
jdg_dl@my-dejanews.com wrote:
>
> Could you cite the ansi/iso reference stating that objects
> cannot move from address A to address B? For objects of the same
> class (not derived), this function will swap everything, including
> the vptrs. Nothing is destructed, constructed and copy constructed.
> Which IMO, is semantically logical for swapping.
Consider a class that has intrusive "next" and "previous" links for
hooking the objects into doubly-linked lists. If you swap two objects by
blind byte copying, the links will become incoherent.
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/10/12 Raw View
In article <361E58CB.167E@wizard.net>,
James Kuyper <kuyper@wizard.net> wrote:
>
> jdg_dl@my-dejanews.com wrote:
> ...
> > Could you cite the ansi/iso reference stating that objects
> > cannot move from address A to address B? For objects of the same
> > class (not derived), this function will swap everything, including
> > the vptrs. Nothing is destructed, constructed and copy constructed.
> > Which IMO, is semantically logical for swapping.
>
> User defined types have user defined semantics for copying. Bitwise
> swapping is often not acceptable. For a simple example, consider an
> object of a user-defined type that contains a pointer to dynamically
> allocated memory, with ownership semantics. The copy constructor and the
> assignment operators are defined to allocate a new piece of memory, and
> then copy over the contents using the source object's pointer. A bitwise
> copy will put the same pointer in two different objects, each of which
> thinks it's the sole owner of that pointer. It's a virtual certainty
> that the attempt will be made to deallocate that memory twice, or to
> access that memory after it's been deallocated. BAD!
Of course, this isn't a problem if the bit-wise copying is only used for
swapping. On the other hand, it isn't rare for an object to contain
pointers to subobjects of itself -- one of the more frequent implementations
of virtual base classes does this, invisible to the user. Swapping such
an object using bitwise copy is a sure invitation to a core dump, or something
worse.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de>
Date: 1998/10/06 Raw View
The template function `byte_swap', see below, is an universal swap
function.
It does swap two objects using the `memcpy' function.
If it is legal, it would be useful for user defined types.
It does allow a swap between two objects of the same or related types.
I know, the second is a bit perverse. :-)
It does work (egcs-1.1), but is it legal?
template <typename T>
void
byte_swap(T& lhs, T& rhs)
{
char temp[sizeof(T)];
memcpy(temp, &lhs, sizeof(T));
memcpy(&lhs, &rhs, sizeof(T));
memcpy(&rhs, temp, sizeof(T));
}
class X {
public:
X(const string& s) : fs1(s) {}
virtual ~X() {}
virtual string func() {return fs1;}
protected:
string fs1;
};
class Y : public X {
public:
Y(const string& s1, const string &s2) : X(s1), fs2(s2) {}
virtual string func() {return fs1 + " " + fs2;}
private:
string fs2;
};
int main(int argc, char** argv)
{
X x("Tom");
Y y("Tim", "John");
cout << x.func() << ' ' << y.func() << '\n';
byte_swap(x, static_cast<X&>(y));
cout << x.func() << ' ' << y.func() << '\n';
}
Ryszard Kabatek
--
Martin-Luther University Halle-Wittenberg
Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany
Tel. +49 3461 46 2487 Fax. +49 3461 46 2129
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jerry Leichter <leichter@smarts.com>
Date: 1998/10/06 Raw View
| The template function `byte_swap', see below, is an universal swap
| function.
| It does swap two objects using the `memcpy' function.
| If it is legal, it would be useful for user defined types. [Is it
| legal?]
What I suppose you mean to ask is: Can a conforming program use this
function. The answer is no. Any code that treats an arbitrary object
as "just a bag of bytes" is not conforming.
For a simple example, consider a class which keeps track of all of its
instances by adding them to a linked list in its constructors, and
deleting them in its destructors. You might have:
[head] -> A -> B -> 0
(A and B are the variables that refer to the two existing instances of
the class.) Now do a byte-swap of A and B. A now points to where B
used to point; B points to where A used to point; and [head] is
unchanged. You're left with:
[head] -> A -> 0
B -> B
B has disappeared from the list of instances, and B now stands alone in
a loop.
A C++ object is *not* a "bag of bytes". (In fact, in C++ standardese,
there's an abbreviation - POD, for Plain Old Data - which refers to
objects of classes that are "just like C structs": They inherit from
nothing and have no member functions or static members, and all their
fields are themselves either POD's or fundamental types. Those, you
could safely swap with your function. For any other type - you need to
know the detailed semantics.)
-- Jerry
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/10/06 Raw View
Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> writes:
> It does swap two objects using the `memcpy' function.
> If it is legal, it would be useful for user defined types.
It is legal, but it invokes undefined behavior if you use it to swap
non-POD types.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:oliva@gnu.org mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/10/08 Raw View
In article <3618D67A.3A251641@rumcajs.chemie.uni-halle.de>,
kabatek@chemie.uni-halle.de wrote:
> The template function `byte_swap', see below, is an universal swap
> function.
> It does swap two objects using the `memcpy' function.
Absolutely. Works like a champ for built-in types.
> If it is legal, it would be useful for user defined types.
It depends on what's in the user-defined type. If it contains a
linked-list pointer, the result may not be anything useful.
If the type has virtual functions or virtual base classes, the
results are undefined -- it may work on compiler A today, but
fail on compiler B, and perhaps even fail on compiler A tomorrow.
> It does work (egcs-1.1), but is it legal?
For "POD" (Plain 'Ol Data) types, it's legal. For "Objects" you
should consider using this code, which (this may surprise you)
often isn't any slower than your version (depending on the data
type it operates on):
template <typename T>void swap(T&lhs, T&rhs) {
T temp(lhs);
lhs = rhs;
rhs = temp;
}
If T has a long involved copy constructor, this will be slower.
Otherwise it may be just as fast. If T is a container type that
recognizes "Copy-On-Write" semantics, this version could actually
be much much faster!
> template <typename T>
> void
> byte_swap(T& lhs, T& rhs)
> {
> char temp[sizeof(T)];
> memcpy(temp, &lhs, sizeof(T));
> memcpy(&lhs, &rhs, sizeof(T));
> memcpy(&rhs, temp, sizeof(T));
> }
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jonah Tsai <jonah@cs.cmu.edu>
Date: 1998/10/09 Raw View
One little reminder, if lhs & rhs are the same object, i.e. memory overlap,
the behavior of memcpy() is undefined. Of course, I'm picking.
Doing byte swap on user defined type (class & struct) is dangerous, say:
class A { /* ... */ }
class B: public A { /* ... */ }
A a;
B b;
A *c = static_cast<A*>(&b);
byte_swap<A>(a, *c);
First, "b" is partially swapped! Oops, unless that's what you intended. I
cheated by casting "b" into type "A", but that is not unrealistic in even a
small program of a few KLOC such that some unknown module created it and
passed it as a type A object.
Second, which virtual table "b" has now??? Hey, it may not even have a
virtual table! It may just work fine on some compilers due to the object
structure chosen, for instance, egcs 1.1 will do the partial swap without
messing up the virtual function table, if it has one (I verified that by
calling a method defined in class B). But can that behavior be guaranteed by
all compilers, i.e. specified by ANSI C++ standard? If virtual tables are
swapped, that is scary, because it "may" also swapped the type_info of A & B,
in addition to other even more scary things that we don't even know they
exist. Who knows? It's implementation dependent.
A compiler is free to do the memory swap trick on user-defined types, but as
a programmer, it's not a good idea not to do so.
Of course, it's just my opion, I could be wrong.
Jonah
Ryszard Kabatek wrote:
> The template function `byte_swap', see below, is an universal swap
> function.
> It does swap two objects using the `memcpy' function.
> If it is legal, it would be useful for user defined types.
>
> It does allow a swap between two objects of the same or related types.
> I know, the second is a bit perverse. :-)
>
> It does work (egcs-1.1), but is it legal?
>
> template <typename T>
> void
> byte_swap(T& lhs, T& rhs)
> {
> char temp[sizeof(T)];
> memcpy(temp, &lhs, sizeof(T));
> memcpy(&lhs, &rhs, sizeof(T));
> memcpy(&rhs, temp, sizeof(T));
> }
>
> class X {
> public:
> X(const string& s) : fs1(s) {}
>
> virtual ~X() {}
>
> virtual string func() {return fs1;}
>
> protected:
> string fs1;
> };
>
> class Y : public X {
> public:
> Y(const string& s1, const string &s2) : X(s1), fs2(s2) {}
>
> virtual string func() {return fs1 + " " + fs2;}
>
> private:
> string fs2;
> };
>
> int main(int argc, char** argv)
> {
> X x("Tom");
> Y y("Tim", "John");
>
> cout << x.func() << ' ' << y.func() << '\n';
>
> byte_swap(x, static_cast<X&>(y));
>
> cout << x.func() << ' ' << y.func() << '\n';
> }
>
> Ryszard Kabatek
> --
> Martin-Luther University Halle-Wittenberg
> Department of Physical Chemistry
> Geusaer Str. 88, 06217 Merseburg, Germany
> Tel. +49 3461 46 2487 Fax. +49 3461 46 2129
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jdg_dl@my-dejanews.com
Date: 1998/10/09 Raw View
: Absolutely. Works like a champ for built-in types.
:
: > If it is legal, it would be useful for user defined types.
:
: It depends on what's in the user-defined type. If it contains a
: linked-list pointer, the result may not be anything useful.
: If the type has virtual functions or virtual base classes, the
: results are undefined -- it may work on compiler A today, but
: fail on compiler B, and perhaps even fail on compiler A tomorrow.
Could you cite the ansi/iso reference stating that objects
cannot move from address A to address B? For objects of the same
class (not derived), this function will swap everything, including
the vptrs. Nothing is destructed, constructed and copy constructed.
Which IMO, is semantically logical for swapping.
Joel de Guzman
PS. Swapping derived objects with this will cause object slicing.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/10/10 Raw View
jdg_dl@my-dejanews.com wrote:
...
> Could you cite the ansi/iso reference stating that objects
> cannot move from address A to address B? For objects of the same
> class (not derived), this function will swap everything, including
> the vptrs. Nothing is destructed, constructed and copy constructed.
> Which IMO, is semantically logical for swapping.
User defined types have user defined semantics for copying. Bitwise
swapping is often not acceptable. For a simple example, consider an
object of a user-defined type that contains a pointer to dynamically
allocated memory, with ownership semantics. The copy constructor and the
assignment operators are defined to allocate a new piece of memory, and
then copy over the contents using the source object's pointer. A bitwise
copy will put the same pointer in two different objects, each of which
thinks it's the sole owner of that pointer. It's a virtual certainty
that the attempt will be made to deallocate that memory twice, or to
access that memory after it's been deallocated. BAD!
There are many, many other ways in which a bitwise copy could be a bad
idea. Basically, any class which has a user-defined copy constructor,
should never by copied without using it.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]