By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,260 Members | 1,318 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,260 IT Pros & Developers. It's quick & easy.

Bit Shifting in structures

P: n/a
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.

Jun 30 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Sekhar wrote:
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.


Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke

Jun 30 '06 #2

P: n/a

Luke Meyers wrote:
Sekhar wrote:
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.


Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke


Sorry for the wrong key word used
I was looking for "Structure Packing" concepts

Jun 30 '06 #3

P: n/a
Sekhar wrote:
Luke Meyers wrote:
Sekhar wrote:
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.


Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke

Sorry for the wrong key word used
I was looking for "Structure Packing" concepts

Such things are implementation defined. If an implementation requires
particular alignments for certain data types, struct members will be
aligned to comply with those rules.
--
Ian Collins.
Jun 30 '06 #4

P: n/a

Ian Collins wrote:
Sekhar wrote:
Luke Meyers wrote:
Sekhar wrote:

can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.

Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke

Sorry for the wrong key word used
I was looking for "Structure Packing" concepts

Such things are implementation defined. If an implementation requires
particular alignments for certain data types, struct members will be
aligned to comply with those rules.
--
Ian Collins.


thanks for this. Can you elaborate on this by taking a small sample
structure.

Jun 30 '06 #5

P: n/a
Sekhar wrote:
Ian Collins wrote:
Sekhar wrote:
Luke Meyers wrote:
Sekhar wrote:
>can anyone shed some light on "Bit Shifting" of structures?
>
>I have a doubt whether i am using the right key word or not.

Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke
Sorry for the wrong key word used
I was looking for "Structure Packing" concepts


Such things are implementation defined. If an implementation requires
particular alignments for certain data types, struct members will be
aligned to comply with those rules.
--
Ian Collins.

thanks for this. Can you elaborate on this by taking a small sample
structure.

Say an int has to be aligned on 4 byte boundaries (a common case),

struct X{
char a;
int b;
};

sizeof(X) would be be 8 bytes, one for the char, three padding bytes and
4 for the int.

By the way, you should set your newsreader not to quote sigs (the bit
below the --). This is normally the default setting.

--
Ian Collins.
Jun 30 '06 #6

P: n/a
I am new to gmail.How can i disable this option?

Jun 30 '06 #7

P: n/a

"Sekhar" <su****@gmail.com> wrote:
I was looking for "Structure Packing" concepts.


Unfortunately, the way of doing that varies drastically from
one compiler to another.

My compiler (djgpp) sets packing to 1 byte (instead of the
usual 4) if I put "__attribute__ ((packed))" at the end of
struct members, like so:

// 24-bit color data for a pixel (NOTE PACKING!):
struct Color
{
uint8 blue __attribute__ ((packed));
uint8 green __attribute__ ((packed));
uint8 red __attribute__ ((packed));
uint8 dummy __attribute__ ((packed));
};

But this may not work with your compiler. Consult its
documentation regarding "packing of structs".

--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net (put "[ciao]" in subject to bypass spam filter)
http://home.pacbell.net/earnur/

Jun 30 '06 #8

P: n/a
Robbie Hatley posted:

// 24-bit color data for a pixel (NOTE PACKING!):
struct Color
{
uint8 blue __attribute__ ((packed));
uint8 green __attribute__ ((packed));
uint8 red __attribute__ ((packed));
uint8 dummy __attribute__ ((packed));
};

If you want a portable method, do this:

#include <climits>
#include <boost/static_assert.hpp>

struct Colour {

BOOST_STATIC_ASSERT( 8 == CHAR_BIT );

unsigned char components[4];

unsigned char &blue;
unsigned char &green;
unsigned char &red;
unsigned char &dummy;

Colour() : blue(components[0]),
green(components[1]),
red(components[2]),
dummy(components[3])
{}

};

--

Frederick Gotham
Jun 30 '06 #9

P: n/a

"Frederick Gotham" <fg*******@SPAM.com> wrote in message
news:G7*******************@news.indigo.ie...
Robbie Hatley posted:

// 24-bit color data for a pixel (NOTE PACKING!):
struct Color
{
uint8 blue __attribute__ ((packed));
uint8 green __attribute__ ((packed));
uint8 red __attribute__ ((packed));
uint8 dummy __attribute__ ((packed));
};

If you want a portable method, do this:

#include <climits>
#include <boost/static_assert.hpp>

struct Colour {

BOOST_STATIC_ASSERT( 8 == CHAR_BIT );


Well, this assumes you've got the Boost libraries.

To the OP: _why_ do you want to "pack" the data? What problem are you
trying to solve?

-Howard


Jun 30 '06 #10

P: n/a
Howard wrote:
"Frederick Gotham" <fg*******@SPAM.com> wrote
If you want a portable method, do this:

#include <climits>
#include <boost/static_assert.hpp>

struct Colour {

BOOST_STATIC_ASSERT( 8 == CHAR_BIT );


Well, this assumes you've got the Boost libraries.


One could easily extract BOOST_STATIC_ASSERT or Loki's STATIC_CHECK. I
know that at least the latter is self-contained in a single header.
Alternately, you could put a run-time assertion in the constructor, or
you could just rely on the user to make sure that there are 8 bits per
char (not the best option).

Cheers! --M

Jun 30 '06 #11

P: n/a
Howard posted:

Well, this assumes you've got the Boost libraries.
At the very least, he could just take the macro definition, which I
presume is something like:

#define BOOST_STATIC_ASSERT(expr) typedef char StaticAssertion[ \
(expr) ? 3 : -5 ]

To the OP: _why_ do you want to "pack" the data? What problem are you
trying to solve?

I presume the wants to access it as a 32-Bit unsigned int, e.g.:

void FuncWants32Bit( unsigned ); /* Defined elsewhere */

int main()
{
Colour cr;

cr.blue = 5;
cr.green = 8;
cr.red = 322;
cr.dummy = 0;

FuncWants32Bit( reinterpret_cast<unsigned&>(cr) );
}

--

Frederick Gotham
Jun 30 '06 #12

P: n/a

"Frederick Gotham" <fg*******@SPAM.com> wrote in message
news:wP*******************@news.indigo.ie...
Howard posted:

Well, this assumes you've got the Boost libraries.


At the very least, he could just take the macro definition, which I
presume is something like:

#define BOOST_STATIC_ASSERT(expr) typedef char StaticAssertion[ \
(expr) ? 3 : -5 ]


What is that? It looks like it declares an array of either size 3 or
size -5. Why would you want to do that? Granted, declaring an array of
size -5 causes a compiler error, but getting a "negative subscript" error is
hardly going to help the user know what the problem is.
To the OP: _why_ do you want to "pack" the data? What problem are you
trying to solve?

I presume the wants to access it as a 32-Bit unsigned int, e.g.:


Based on what? All he said was:

I was looking for "Structure Packing" concepts

Pretty vague as to purpose. Perhaps he's looking into network transmission,
or serialization, or reducing memory useage. No real way to know unless he
answers.

-Howard


Jun 30 '06 #13

P: n/a
Howard posted:

What is that? It looks like it declares an array of either size 3 or
size -5. Why would you want to do that? Granted, declaring an array
of size -5 causes a compiler error, but getting a "negative subscript"
error is hardly going to help the user know what the problem is.

But he should be pointed to the correct line in the correct file, which is
adequate in my opinion.

--

Frederick Gotham
Jun 30 '06 #14

P: n/a
Sekhar wrote:
Luke Meyers wrote:
Sekhar wrote:
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.


Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.

Luke


Sorry for the wrong key word used
I was looking for "Structure Packing" concepts


I had not heard this phrase, but when I google for "structure packing"
"c++" I see that it is an extension supported by some compilers. Hence
nonstandard, hence off-topic here.

In the future, please try to:
1) Be on-topic (read the FAQ for how).
2) Ask a question which amounts to something more substantial than
"please google the following phrase for me and summarize the results."
Do your own googling, then formulate a specific question based on
anything you have trouble understanding.

Luke

Jun 30 '06 #15

P: n/a
"Howard" <al*****@hotmail.comwrote:
"Frederick Gotham" <fg*******@SPAM.comwrote:
Robbie Hatley posted:

// 24-bit color data for a pixel (NOTE PACKING!):
struct Color
{
uint8 blue __attribute__ ((packed));
uint8 green __attribute__ ((packed));
uint8 red __attribute__ ((packed));
uint8 dummy __attribute__ ((packed));
};
(snip stuff here for brevity)

To the OP: _why_ do you want to "pack" the data? What problem are you
trying to solve?
The struct you quote doesn't belong to the OP; it's mine.

The reason I pack this particular struct is to conform to
the file specification for *.bmp bitmap files, which want
pixels represented in the file like so:

pixel 1 blue
pixel 1 green
pixel 1 red
pixel 1 dummy
pixel 2 blue
pixel 2 green
pixel 2 red
pixel 2 dummy

EXACTLY like that. Any padding of struct members to bring
them to 32-bit boundaries would give you THIS instead:

pixel 1 blue
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 1 green
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 1 red
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 1 dummy
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 2 blue
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 2 green
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 2 red
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE
pixel 2 dummy
EXTRA PADDING BYTE
EXTRA PADDING BYTE
EXTRA PADDING BYTE

Which, needless to say, would totally #$%^ up the file structure.
Pardon my French.

Now, padding of this particular struct *AS A WHOLE* to bring it to
a 32-bit boundary wouldn't matter, because the desired size is
already 32 bits.

However, there are two header sections at the top of a *.bmp file
which are 14 and 40 bytes respectively. I also use structs for
those, and it is NOT acceptable for those to be padded out to
32 and 64 bits, or whatever; so I use __attribute__ ((packed))
to keep them at exactly 14 and 40 bytes:

#define PACKED __attribute__ ((packed))

// Bmfh == Bit Map File Header
struct Bmfh
{
uint16 filetype PACKED; // File type, always "BM"
uint32 filesize PACKED; // File size, always 54+matrixsize
uint16 reserved1 PACKED; // Reserved 1 (not used)
uint16 reserved2 PACKED; // Reserved 2 (not used)
uint32 offset PACKED; // Offset to data, always 54
};

// Bmih == Bit Map Information Header
struct Bmih
{
uint32 bmihsize PACKED; // size of this header (40)
uint32 imagewidth PACKED; // width of image in pixels
uint32 imageheight PACKED; // height of image in pixels
uint16 planes PACKED; // number of image planes
uint16 bitcount PACKED; // bits per pixel
uint32 compression PACKED; // compression code
uint32 matrixsize PACKED; // matrix size in bytes
uint32 xpixelspermeter PACKED; // H pixels per meter
uint32 ypixelspermeter PACKED; // V pixels per meter
uint32 colorsused PACKED; // colors used
uint32 colorsimportant PACKED; // colors important
};

It just simplifies writing this stuff out to a binary file if
you can write whole structs at a time without having to worry
either about member padding or struct padding screwing-up the
file alignment.

--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net
(put "[usenet]" in subject to bypass spam filter)
http://home.pacbell.net/earnur/
Jul 2 '06 #16

P: n/a
"Luke Meyers" <n.***********@gmail.comwrote:
Sekhar wrote:
Luke Meyers wrote:
Sekhar wrote:
can anyone shed some light on "Bit Shifting" of structures?

I have a doubt whether i am using the right key word or not.
>
Your question is vague. Please post complete, compilable code
illustrating your best attempt to do whatever it is you're trying to
do.
>
Luke
Sorry for the wrong key word used
I was looking for "Structure Packing" concepts

I had not heard this phrase, but when I google for "structure packing"
"c++" I see that it is an extension supported by some compilers. Hence
nonstandard, hence off-topic here.
This is "comp.lang.c++", not "comp.std.c++". There is no requirement
to keep topics of conversation to arguments about the standard.
The LANGUAGE C++ (see the "lang" in the group name?) predates the
current standard by quite a few years. I get pretty fed up with
exchanges like this:

Person 1: "How do you XXX?"
Person 2: "The standard doesn't say how to do XXX. Hence,
you're off-topic! Read the FAQ!"

Translation: Person 2 is too lazy to think of a way to do XXX, and
too power-hungry to resist an opportunity to berate person 1. Note
that in these cases, the FAQ rarely actually answers the question
at hand, but is useful as a weapon in a power play.
In the future, please try to:
1) Be on-topic (read the FAQ for how).
All the posters involved were.
2) Ask a question which amounts to something more substantial than
"please google the following phrase for me and summarize the results."
I'm sure the OP probably did.
Do your own googling, then formulate a specific question based on
anything you have trouble understanding.
The OP did. The answer is, there's no "standard" way, but most
compilers do have ways of doing that, because people who use
this LANGUAGE (as in comp.LANG.c++) often need to due this,
even if the STANDARD (as in comp.STD.c++) doesn't say how.

I gave the way gcc does it. This is one of the most popular
compilers around, so this information should be widely useful.

Other posters gave the "boost" way, which is probably more
portable, provided boost supports one's favorite compiler.
(In my case, it doesn't.)

--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net
(put "[usenet]" in subject to bypass spam filter)
http://home.pacbell.net/earnur/
Jul 2 '06 #17

P: n/a

Frederick Gotham wrote:
>
struct Colour {

BOOST_STATIC_ASSERT( 8 == CHAR_BIT );

unsigned char components[4];

unsigned char &blue;
unsigned char &green;
unsigned char &red;
unsigned char &dummy;

Colour() : blue(components[0]),
green(components[1]),
red(components[2]),
dummy(components[3])
{}

};
sizeof(Colour) is 20 on Visual C++ 8.0 compiling for 32-bit x86, not 4,
as expected. The refrences each seem to take storage which isn't
practical.

A typical approach in graphics programming scene is to use unions, the
following undefined behaviour invoking union is fairly typical from
what I've seen.

struct color {
union {
struct { unsigned char b,g,r,a; };
unsigned int u;
};
};

That's "ideal", but uses unnamed structs which isn't standard. Also
writing to b,g,r or a and reading from u and vice-versa is illegal. But
it is done anyway.

I myself use the following "reinterpret_cast" hack, which again is UB..

namespace blabla {
typedef ... uint8; // omitted
typedef ... uint32; // omitted

struct ucolor
{
#ifdef FUSIONCORE_LITTLE_ENDIAN

uint8 b, g, r, a;

ucolor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
: b(blue), g(green), r(red), a(alpha)
{
}

#endif

#ifdef FUSIONCORE_BIG_ENDIAN

uint8 a, r, g, b;

ucolor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
: a(alpha), r(red), g(green), b(blue)
{
}

#endif

ucolor(uint32 v)
{
*this = v;
}

ucolor()
{
}

~ucolor()
{
}

ucolor& operator = (uint32 v)
{
reinterpret_cast<uint32*>(this)[0] = v;
return *this;
}

operator uint32 () const
{
return reinterpret_cast<const uint32&>(*this);
}

const ucolor& operator + () const
{
return *this;
}

ucolor operator - () const
{
uint32 v = *this;
return ucolor(v ^ 0xffffffff);
}
};

The idea with this is that the "ucolor" maps to a very common argb8888
pixel-/texelformat layout. The caveat of this particular approach are:

- unreasonable reinterpret_cast expectation (implementation specific,
UB assumed automaticly on unknown impementation)
- only supports non-standard concept of "endianess" (big- and little
endian are supported)
- assumes char is 8 bits
- assumes the platform has 32 bit unsigned integer type (or can
implement fall-back using the language, but this requires 8 or 16 bit
unsigned type to be present to pull this off, say, 64-bit integer
wouldn't fill the design criterias of matching the argb8888 layout)

First things that spring to mind. The struct *could* be named, but this
is something that wasn't wanted in the design. :)

The reinterpret_cast issue is fixable easily, the uint32 could be built
with bit-shifting and or'ing at additional cost. The decision to do so
has been postponed for c++ implementations that break (correctly so!)
with this code.

There's more than that to it but that covers the basics. Additional
note is that hackery like this is typically avoided at all costs but
this is a case where it's warranted from our point of view (performance
in per-pixel operations, where the code is still written in HLL not
generated by the online code generator :)

Jul 2 '06 #18

P: n/a
persenaama posted:

A typical approach in graphics programming scene is to use unions, the
following undefined behaviour invoking union is fairly typical from
what I've seen.

struct color {
union {
struct { unsigned char b,g,r,a; };
unsigned int u;
};
};

The compiler may very likely put padding between "b", "g", "r" and "a".

Here's the way I look at it:

You want a 32-Bit unsigned integer to represent a colour. You want to
set each of its bytes individually as they correspond to the elements
which compose that colour.

Sounds like you want a bitfield to me.

That's "ideal", but uses unnamed structs which isn't standard. Also
writing to b,g,r or a and reading from u and vice-versa is illegal. But
it is done anyway.

I can't remember what ever came of that thread on comp.std.c++ regarding
"Irrational Rules"; I might have a look in a few minutes.

--

Frederick Gotham
Jul 2 '06 #19

P: n/a

Frederick Gotham wrote:
You want a 32-Bit unsigned integer to represent a colour. You want to
set each of its bytes individually as they correspond to the elements
which compose that colour.

Sounds like you want a bitfield to me.
I thought so too: but the problem is that then that writing a component
is and/or sequence instead of write when byte-write could be done
(assuming x86 where I do most of my work).

(to be honest) The most common usage pattern is of form:

uint32 v = *src++;
*dest++ = (v & ?) << ?) | (v & ?) >?) | ...;

"read once and process" -pattern so to speak. The number of
permutations actually blows up quickly in this kind of work so offline
code generation isn't very practical anyway, with the latest
arrangement a question begs to be asked why the "ucolor" should be in
the critical path these days at all: it isn't.

Point being that has been already been considered, too. It would be the
*safest* approach, definitely. I've done this sort of thing a slight
amount, the current mindset I've got is that I don't write code that
touches fragments in HLL, unless it is some prototyping work only
(where performance isn't that relevant). In this light it's worth
switching over to get rid of the reinterpret_cast's, in this kind of
use they aren't something anyone I know of would be proud about. ;-)

Jul 2 '06 #20

P: n/a
Robbie Hatley wrote:
2) Ask a question which amounts to something more substantial than
"please google the following phrase for me and summarize the results."

I'm sure the OP probably did.
No, the OP did not. The OP asked a vague question which amounted to no
more than my rephrasing, and when asked for clarification, posted
*another* vague question which amounted to the same.
Do your own googling, then formulate a specific question based on
anything you have trouble understanding.

The OP did.
What was the question? All I see is something essentially of the form
"what is X?," and I think "STFW and ask a real question" is a perfectly
reasonable response to that, especially on the second try.

I *do* take your point in general, I really do -- there are certainly
cases where some of us, myself included, get fed up enough with the
off-topic and lazy posts that occur so frequently that we narrow our
view excessively and become dismissive of posts which are more
borderline. However, I think you've chosen a poor example as an object
lesson. The OP simply didn't formulate a question, even when
explicitly asked to do so.

Luke

Jul 2 '06 #21

P: n/a
"Luke Meyers" wrote:
Robbie Hatley wrote:
2) Ask a question which amounts to something more substantial than
"please google the following phrase for me and summarize the results."
I'm sure the OP probably did.

No, the OP did not. The OP asked a vague question which amounted to no
more than my rephrasing, and when asked for clarification, posted
*another* vague question which amounted to the same.
Do your own googling, then formulate a specific question based on
anything you have trouble understanding.
The OP did.

What was the question? All I see is something essentially of the form
"what is X?," and I think "STFW and ask a real question" is a perfectly
reasonable response to that, especially on the second try.

I *do* take your point in general, I really do -- there are certainly
cases where some of us, myself included, get fed up enough with the
off-topic and lazy posts that occur so frequently that we narrow our
view excessively and become dismissive of posts which are more
borderline. However, I think you've chosen a poor example as an object
lesson. The OP simply didn't formulate a question, even when
explicitly asked to do so.
Remember, though, that many folks here are not from USA or UK,
they're from India, China, Bangladesh, Bhutan, or whatever.
English is a second language for them, and their vocabularies
are a bit thin. That alone accounts for some perceived vagueness.
It doesn't mean that they're stupid, or lazy, or incapable of
learning about C++ from interactions in this group.

(Though I admit that a few of the folks who come here clearly ARE
incapable of learning from this group.)

There are, as you say, many posts that are very off-topic.
I usually tell the person "go to group comp.xxx.xxx.xxx" as
appropriate. Usually comp.os.ms-windows.programmer.win32 .
Some days, it seems half the posts here should be there instead.

And when I know a question is covered in the FAQ, I often say,
"see FAQ section xxx: (hyperlink to section)".

But with some topics, where else are you going to go? Things
like "what happens to data dynamically allocated with new and
accidentally left on the stack when the program exits?" Or
"how many bits is long int?" Or "how do I pack structs?" Or
"How do I write a state machine in C++?" Those are all valid
questions, even though in every case the C++ standard says,
"Gee, I don't know." But there usually ARE meaningful
answers to those questions, and those answers usually are NOT
in the FAQ; they're in the heads of the many fine programmers
who hang out here.

Actually, that is exactly the kind of topic that piques my
interest, and I tend to get involved more in those threads
than in threads where someone asks a question that I (or the
person asking the question, for that matter) could answer by
taking 20 seconds to flip to the appropriate section of
document ISO/IEC-14882. Yawn. Give me something more outre
to talk about! :-)

--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net
(put "[usenet]" in subject to bypass spam filter)
http://home.pacbell.net/earnur/
Jul 3 '06 #22

P: n/a
In message <G7*******************@news.indigo.ie>, Frederick Gotham
<fg*******@SPAM.comwrites
>Robbie Hatley posted:

> // 24-bit color data for a pixel (NOTE PACKING!):
struct Color
{
uint8 blue __attribute__ ((packed));
uint8 green __attribute__ ((packed));
uint8 red __attribute__ ((packed));
uint8 dummy __attribute__ ((packed));
};


If you want a portable method, do this:

#include <climits>
#include <boost/static_assert.hpp>

struct Colour {

BOOST_STATIC_ASSERT( 8 == CHAR_BIT );

unsigned char components[4];

unsigned char &blue;
unsigned char &green;
unsigned char &red;
unsigned char &dummy;

Colour() : blue(components[0]),
green(components[1]),
red(components[2]),
dummy(components[3])
{}

};
Fine, except that's no longer a POD, can't be copied or assigned, and is
quite likely to take up 5 times as much space.

--
Richard Herring
Jul 6 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.