I have ome new code which has to work with some legacy code which does
a lot of memset's and memcmp's on structs of PODs. This leads me to
want to do stuff like this:
struct foo
{
unsigned char c1_;
unsigned short us1_;
};
std::vector<foo> fooVect;
memset(&foo, 0, sizeof(foo));
fooVect.push_back(foo);
The compiler I've tested this with uses 4 byte alignment by default and
hence puts in some padding bytes. Looking at the copy of foo which is
now at fooVect[0], the padding bytes have random values. The zero
setting of the padding bytes has not been preserved when foo has been
copied to the vector.
I'd expect that what happens to padding bytes is undefined, but it
would be useful to have them preserved as zero. Any sensible,
non-kludgy, portable way of doing this?
--
Simon Elliott http://www.ctsn.co.uk 6 2938
Simon Elliott wrote: I have ome new code which has to work with some legacy code which does a lot of memset's and memcmp's on structs of PODs. This leads me to want to do stuff like this:
struct foo { unsigned char c1_; unsigned short us1_; };
std::vector<foo> fooVect;
memset(&foo, 0, sizeof(foo)); fooVect.push_back(foo);
The compiler I've tested this with uses 4 byte alignment by default and hence puts in some padding bytes. Looking at the copy of foo which is now at fooVect[0], the padding bytes have random values. The zero setting of the padding bytes has not been preserved when foo has been copied to the vector.
I'd expect that what happens to padding bytes is undefined, but it would be useful to have them preserved as zero.
How would it be useful? I am genuinely curious.
Any sensible, non-kludgy, portable way of doing this?
I don't think so. If you know what the size of 'foo' is with your current
alignment requirements, you could add
char padding[known_size_of_foo - sizeof(short) - 1];
To know what the size of 'foo' is, you need to replicate it
struct foo_replica {
char c; short s;
};
and use *its* size instead. Basically it should be
struct foo_replica
{
char c; short s;
};
struct foo
{
unsigned char c1_;
unsigned short us1_;
char padding[sizeof(foo_replica) - 1 - sizeof(short)];
};
Victor
Simon Elliott wrote: I have ome new code which has to work with some legacy code which does a lot of memset's and memcmp's on structs of PODs. This leads me to want to do stuff like this:
struct foo { unsigned char c1_; unsigned short us1_; };
std::vector<foo> fooVect;
memset(&foo, 0, sizeof(foo)); fooVect.push_back(foo);
The compiler I've tested this with uses 4 byte alignment by default and hence puts in some padding bytes. Looking at the copy of foo which is now at fooVect[0], the padding bytes have random values. The zero setting of the padding bytes has not been preserved when foo has been copied to the vector.
I'd expect that what happens to padding bytes is undefined, but it would be useful to have them preserved as zero. Any sensible, non-kludgy, portable way of doing this?
struct foo
{
foo() { memset( this, 0, sizeof( foo ) ); }
foo( const foo& Arg ) { memcpy( this, Arg, sizeof( foo ) ); }
unsigned char c1_;
unsigned short us1_;
};
But note: This works as long as data members of that struct qualify
the struct as a POD (It is no longer one, since a POD doesn't have
a ctor). At the moment somebody introdues a std::string or any other
class with dynamic management in it, it will fail miserably.
--
Karl Heinz Buchegger kb******@gascad.at
Simon Elliott wrote: The compiler I've tested this with uses 4 byte alignment by default
and hence puts in some padding bytes. Looking at the copy of foo which is now at fooVect[0], the padding bytes have random values.
Sure but who cares? You can neither access these bytes nor take
any advantage of them: they are an implementation detail of the
compiler, nothing more. They might highlight some programming
errors, though: e.g. they may cause unterminated C-strings to
become terminated.
I'd expect that what happens to padding bytes is undefined, but it would be useful to have them preserved as zero.
Why?
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
On 23/02/2005, Victor Bazarov wrote: I'd expect that what happens to padding bytes is undefined, but it would be useful to have them preserved as zero.
How would it be useful? I am genuinely curious.
Down in the legacy code, memcmp() is used extensively to compare these
things. Unfortunately, memcmp() will compare things like padding bytes,
trailing bytes in C strings etc. So either I find a way of doing this,
or I have to make some significant changes to legacy code. Any sensible, non-kludgy, portable way of doing this?
I don't think so. If you know what the size of 'foo' is with your current alignment requirements, you could add
char padding[known_size_of_foo - sizeof(short) - 1];
To know what the size of 'foo' is, you need to replicate it
struct foo_replica { char c; short s; };
and use its size instead. Basically it should be
struct foo_replica { char c; short s; };
struct foo { unsigned char c1_; unsigned short us1_; char padding[sizeof(foo_replica) - 1 - sizeof(short)]; };
I'm not convinced that this will work because the compiler inserts
padding bytes between c1_ and us1_ so that they align optimally for the
target processor (4 byte boundaries I think in the case of the compiler
I'm using at the moment.) However, perhaps I could do something along
similar lines:
struct foo_holder
{
union
{
foo foo_;
char padding_[sizeof(foo)];
}
};
Then my vector would be a vector of foo_holder, and I'd pass
foo_holder::foo_ down to the legacy code. I expect I could have a
templated holder struct which could hold all the legacy structs.
Or I could push an undefined foo onto the vector, and do something
like:
memset(&fooVect.back(), 0, sizeof(foo));
then fill in foo's fields as referenced by fooVect.back()
--
Simon Elliott http://www.ctsn.co.uk
Simon Elliott wrote: Down in the legacy code, memcmp() is used extensively to compare
these things. Unfortunately, memcmp() will compare things like padding
bytes, trailing bytes in C strings etc. So either I find a way of doing
this, or I have to make some significant changes to legacy code.
Hm, OK. I don't think this is the best way to it but it seems like a
reasonable request. Do you need to pass (pointers to) arrays of your
type? If not, you could use something like this:
/**/ struct wrapper
/**/ {
/**/ wrapper() { std::memset(&m_foo, 0, sizeof(foo)); }
/**/ wrapper(wrapper const& w) {
/**/ std::memcpy(&m_foo, &w.mem_foo, sizeof(foo));
/**/ foo m_foo;
/**/ };
Even if you need arrays of 'foo's, you might be able to use this
wrapper technique, if 'sizeof(wrapper) == sizeof(foo)': you could
just reinterpret_cast to the appropriate type...
However, perhaps I could do something along similar lines:
struct foo_holder { union { foo foo_; char padding_[sizeof(foo)]; } };
Why use a union? If you use a wrapper, use it with appropriate
constructors...
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
"Dietmar Kuehl" <di***********@yahoo.com> writes: Simon Elliott wrote: The compiler I've tested this with uses 4 byte alignment by default and hence puts in some padding bytes. Looking at the copy of foo which is now at fooVect[0], the padding bytes have random values.
Sure but who cares? You can neither access these bytes nor take any advantage of them: they are an implementation detail of the compiler, nothing more. They might highlight some programming errors, though: e.g. they may cause unterminated C-strings to become terminated.
I'd expect that what happens to padding bytes is undefined, but it would be useful to have them preserved as zero.
Why?
It can help hide programming errors. Remember, the longer a
programming error goes undected, the more chances it has to cause
an embarassing crash during a demo. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Jason Heyes |
last post by:
To my understanding, std::vector does not use reference counting to avoid
the overhead of copying and initialisation. Where can I get a reference
counted implementation of std::vector? Thanks.
|
by: Janina Kramer |
last post by:
hi ng,
i'm working on a multiplayer game for a variable number of players and on the client side, i'm using a std::vector<CPlayer> to store
informatik about the players. CPlayer is a class that...
|
by: Anonymous |
last post by:
Is there a non-brute force method of doing this?
transform() looked likely but had no predefined function object.
std::vector<double> src;
std::vector<int> dest;
...
|
by: Michael Hopkins |
last post by:
Hi all
I want to create a std::vector that goes from 1 to n instead of 0 to n-1.
The only change this will have is in loops and when the vector returns
positions of elements etc. I am calling...
|
by: Ross A. Finlayson |
last post by:
I'm trying to write some C code, but I want to use C++'s std::vector.
Indeed, if the code is compiled as C++, I want the container to
actually be std::vector, in this case of a collection of value...
|
by: zl2k |
last post by:
hi, c++ user
Suppose I constructed a large array and put it in the std::vector in a
function and now I want to return it back to where the function is called.
I can do like this:
...
|
by: Peter Olcott |
last post by:
I am trying to refer to the same std::vector in a class by two different names,
I tried a union, and I tried a reference, I can't seem to get the syntax right.
Can anyone please help? Thanks
|
by: aaragon |
last post by:
I am trying to create a vector of type T and everything goes fine until
I try to iterate over it. For some reason, the compiler gives me an
error when I declare
std::vector<T>::iterator iter;...
|
by: jubelbrus |
last post by:
Hi
I'm trying to do the following.
#include <vector>
#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/tuple/tuple.hpp>
class {
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
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,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
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...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
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...
| |