Dear all,
I have an existing piece of code with a struct with some PODs.
struct A
{
int x;
int y;
};
This struct is created somewhere and initialized via a memset.
A a;
memset(&a,0,sizeof(A));
Now I want to extend the structure with an object, e.g a vector:
struct A
{
int x;
int y;
std::vector<int> z;
};
The sequence
A a;
memset(&a,0,sizeof(A));
would be fatal now, because I overwrite the instanciated vector a.z.
In reality the struct is very huge with a bunch of PODs inside, so using a
ctor would be possible, but quite a lot of work. (I am also scared to miss
something). How would you proceed to avoid the devastating memset?
I thought of kind of
struct A
{
int x;
int y;
int no_memsetbeyond_this_point;
std::vector<int> z;
};
and
A a;
memset(&a,0,&a.no_memsetbeyond_this_point-&a);
It is not really nice, but I have to avoid as much code-rework as possible
for the moment.
Kind regards,
Patrick 14 8305
* Patrick Kowalzick: Dear all,
I have an existing piece of code with a struct with some PODs.
struct A { int x; int y; };
This struct is created somewhere and initialized via a memset.
A a; memset(&a,0,sizeof(A));
Now I want to extend the structure with an object, e.g a vector:
struct A { int x; int y; std::vector<int> z; };
When you have public non-POD members you need to redesign.
The sequence
A a; memset(&a,0,sizeof(A));
would be fatal now, because I overwrite the instanciated vector a.z.
In reality the struct is very huge with a bunch of PODs inside, so using a ctor would be possible, but quite a lot of work. (I am also scared to miss something). How would you proceed to avoid the devastating memset?
When you a "very huge" struct you need to redesign.
But possibly you need to practice that on some smaller test programs
first.
For now, rename the orginal struct to PodA,
struct PodA { ... };
then derive struct A from that,
struct A: PodA
{
A(): PodA() {}
std::vector<int> z;
};
and also check that your compiler supports default-initialization of
POD's (unfortunately some don't).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Hello Alf, struct A { int x; int y; std::vector<int> z; }; When you have public non-POD members you need to redesign.
Normally I'd never use struct for more complex things :). In reality the struct is very huge with a bunch of PODs inside, so using a ctor would be possible, but quite a lot of work. (I am also scared to miss something). How would you proceed to avoid the devastating memset?
When you a "very huge" struct you need to redesign.
Hmm, might be. Lets say very huge in this context is nothing elses than: I
do not want to initialize all the members.
For now, rename the orginal struct to PodA,
struct PodA { ... };
then derive struct A from that,
struct A: PodA { A(): PodA() {} std::vector<int> z; };
Perfect. Thats a rather good solution. Anyway for this case I will change to
struct PodA
{
PodA() { memset(this,0,sizeof(PodA)); }
...
};
struct A: PodA
{
std::vector<int> z;
};
This is not nice (ok it is ugly), but closer to the original code.
and also check that your compiler supports default-initialization of POD's (unfortunately some don't).
I can not, as support for different compiliers has to be assured.
Thanks, that's really good solution.
Regards,
Patrick
On Thu, 19 Jan 2006 14:57:34 +0100, "Patrick Kowalzick"
<pa***************@mapandguide.de> wrote: Dear all,
I have an existing piece of code with a struct with some PODs.
struct A { int x; int y; };
This struct is created somewhere and initialized via a memset.
A a; memset(&a,0,sizeof(A));
Now I want to extend the structure with an object, e.g a vector:
struct A { int x; int y; std::vector<int> z; };
The sequence
A a; memset(&a,0,sizeof(A));
would be fatal now, because I overwrite the instanciated vector a.z.
<snip>
You may create a non-virtual base class with only POD data and inherit
from it. In such a way, you could still a memset, but only with thiis
base class.
struct A_
{
int x;
int y;
};
struct A:public A_
{
A() {memset(static_cast<A_ *>(this),0,sizeof(A_);}
std::vector<int> z;
};
Regards,
Zara
Patrick Kowalzick wrote: Dear all,
I have an existing piece of code with a struct with some PODs.
struct A { int x; int y; };
This struct is created somewhere and initialized via a memset.
[]
Overload memset() in the same header where A is declared:
void memset(A*, int, size_t);
Note that this overload won't be called if memset is invoked as:
memset(void*)&a, ...);
A more proper way would be to redesign the code, so that it don't do
memset on A's anymore.
Alf P. Steinbach wrote: * Patrick Kowalzick: Dear all,
I have an existing piece of code with a struct with some PODs.
struct A { int x; int y; };
This struct is created somewhere and initialized via a memset.
A a; memset(&a,0,sizeof(A));
Now I want to extend the structure with an object, e.g a vector:
struct A { int x; int y; std::vector<int> z; };
I have a follow on question to this. Given:
unsigned int const max_id = 5;
unsigned int const max_participants = 5;
struct some_struct
{ int some_param;
some_struct()
: some_param( -1) {}
};
struct some_other_struct
{ int some_var;
int some_size;
unsigned char* ptr;
some_other_struct()
: some_var(-1)
, some_size(-1)
, ptr(0)
{}
};
struct someImportantData {
unsigned int c_style_arr[ max_participants ];
some_struct c_style_arr2[ max_id ] [ max_participants ];
some_other_struct c_style_arr3[ max_participants ];
};
int main()
{
someImportantData sid;
for ( int idx(0); idx < max_participants; ++idx )
{
sid.c_style_arr[ idx ] = idx ;
}
typedef std::vector<unsigned int> UINT_VEC;
UINT_VEC myVec(&sid.c_style_arr[0],
&sid.c_style_arr[max_participants] );
UINT_VEC::iterator end = myVec.end();
for ( UINT_VEC::const_iterator it = myVec.begin(); it != end; ++it )
{
std::cout << *it << std::endl;
}
}
Now going from c_style_arr to a vector is easy (as shown below) .
How would I do the c_style_arr2 and c_style_arr3? Part of the issue
with c_sytle_arr2 is based on the fact that I'm still experimenting
with 2-d vectors.
In any event, thanks in advance.
Hello Maxim, I have an existing piece of code with a struct with some PODs.
struct A { int x; int y; };
This struct is created somewhere and initialized via a memset.
[]
Overload memset() in the same header where A is declared:
void memset(A*, int, size_t);
Note that this overload won't be called if memset is invoked as:
memset(void*)&a, ...);
A more proper way would be to redesign the code, so that it don't do memset on A's anymore.
The memset are not too often, so I kicked them :). But it seems to be a good
idea to overload memset, perhaps I missed one.....
void memset(A*, int, size_t)
{
assert( "Please, please do not use memset for this struct");
}
Hmm, or static_assert? Would something like this work as static assert?
// forward for allowed memsets
template < typename T > class memset_functor
{
public:
void * operator()( T* dest, int c, size_t count )
{
return memset(dest,c,count);
}
};
// forward for disallowed memsets
template <> class memset_functor< A >
{
public:
void * operator()( A *, int, size_t )
{
// STATIC_ASSERTION
}
};
template < typename T >
void * memset( T* dest, int c, size_t count )
{
return memset_functor<T>()(dest,c,count);
}
Looks funny. I will test this towmorrow :)
Regards,
Patrick
"Patrick Kowalzick" <pa***************@mapandguide.de> skrev i
meddelandet news:ne********************@proxy.mapandguide.de.. . Hello Alf,
struct A { int x; int y; std::vector<int> z; }; When you have public non-POD members you need to redesign.
Normally I'd never use struct for more complex things :).
In reality the struct is very huge with a bunch of PODs inside, so using a ctor would be possible, but quite a lot of work. (I am also scared to miss something). How would you proceed to avoid the devastating memset?
When you a "very huge" struct you need to redesign.
Hmm, might be. Lets say very huge in this context is nothing elses than: I do not want to initialize all the members.
For now, rename the orginal struct to PodA,
struct PodA { ... };
then derive struct A from that,
struct A: PodA { A(): PodA() {} std::vector<int> z; };
Perfect. Thats a rather good solution. Anyway for this case I will change to
struct PodA { PodA() { memset(this,0,sizeof(PodA)); } ... };
But now you have a constructor, so it's not a POD anymore. :-(
This is not nice (ok it is ugly), but closer to the original code.
It is ugly!
Bo Persson
> Hmm, or static_assert? Would something like this work as static assert? // forward for allowed memsets template < typename T > class memset_functor { public: void * operator()( T* dest, int c, size_t count ) { return memset(dest,c,count); } };
// forward for disallowed memsets template <> class memset_functor< A > { public: void * operator()( A *, int, size_t ) { // STATIC_ASSERTION } };
template < typename T > void * memset( T* dest, int c, size_t count ) { return memset_functor<T>()(dest,c,count); }
Looks funny. I will test this towmorrow :)
Ok. I tried it, and it does not work.
The specialization memset_functor< A > will be instanciated, even if there
is no call "memset(A,int,size_t)". Like this the static assertion always
fails.
I use now an easier approach, which works on my compiler, but I am not sure
if it is bullet proof:
template < typename T >
void * memset( TTransferDistlibData2 * dest, T c, size_t count )
{
BOOST_STATIC_ASSERT(FALSE);
return NULL;
}
Calling memset(A,..) fails like this to compile.
Kind regards,
Patrick
Hello Bo, Perfect. Thats a rather good solution. Anyway for this case I will change to
struct PodA { PodA() { memset(this,0,sizeof(PodA)); } ... };
But now you have a constructor, so it's not a POD anymore. :-(
Hmm, ok. I call it "public class with only PODs inside" :). This is not nice (ok it is ugly), but closer to the original code.
It is ugly!
no choice.
Regards,
Patrick
"Patrick Kowalzick" <pa***************@mapandguide.de> skrev i
meddelandet news:ne********************@proxy.mapandguide.de.. . Hello Bo,
Perfect. Thats a rather good solution. Anyway for this case I will change to
struct PodA { PodA() { memset(this,0,sizeof(PodA)); } ... };
But now you have a constructor, so it's not a POD anymore. :-(
Hmm, ok. I call it "public class with only PODs inside" :).
Ok, I didn't explain it properly:
If it's not a POD, you cannot use memset() on it.
That was the original problem! :-)
Bo Persson
Hello Bo, Hmm, ok. I call it "public class with only PODs inside" :). Ok, I didn't explain it properly:
If it's not a POD, you cannot use memset() on it.
Why not? I will take a look in the standard, now, but I was quite sure, that
adding a function to POD-struct will not change the memory structure of this
struct. I see no obvious reason, why this should be dangerous.
If it is dangerous there is still the soution Zara suggests...
That was the original problem! :-)
Not really. The problem was an inner class, which itself may initialize,
inside a structure which is overwirtten by a memset on the outer struct. The
initialization of the inner class is lost (and even worse the instance might
be invalid).
Kind regards,
Patrick
>>> Hmm, ok. I call it "public class with only PODs inside" :). Ok, I didn't explain it properly:
If it's not a POD, you cannot use memset() on it.
Why not? I will take a look in the standard, now, but I was quite sure, that adding a function to POD-struct will not change the memory structure of this struct. I see no obvious reason, why this should be dangerous.
I think, a class with a ctor can still be a POD-class. There fore two cites
from the standard:
"(3.9.10) Arithmetic types (3.9.1), enumeration types, pointer types, and
pointer to member types (3.9.2), and cv-qualified versions of these types
(3.9.3) are collectively called scalar types. Scalar types, POD-struct
types, POD-union types (clause 9), arrays of such types and cv-qualified
versions of these types (3.9.3) are collectively called POD types."
"(9.0.4) {...} A POD-struct is an aggregate class that has no non-static
data members of type non-POD-struct, non-POD-union (or array of such types)
or reference, and has no user-defined copy assignment operator and no
user-defined destructor. Similary, a POD-union is an aggregate union that
has no non-static data members of type non-POD-struct, non-POD-union (or
array of such types) or reference, and has no user-defined copy assignment
operator and no user-defined destructor. A POD class is a class that is
either a POD-struct or a POD-union."
I have no other non-POD typed, nor a copy assignment, nor a dtor. So it is
still a POD? But what about a vtable? Might this still be a POD?
Regards,
Patrick
> I think, a class with a ctor can still be a POD-class. There fore two cites from the standard:
Bullshit :).
"(3.9.10) Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cv-qualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD-struct types, POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types."
"(9.0.4) {...} A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similary, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union."
I have no other non-POD typed, nor a copy assignment, nor a dtor. So it is still a POD? But what about a vtable? Might this still be a POD?
"[8.5.1.1] An aggregate is an array or a class (clause 9) with no
user-declared constructors (12.1), no private or protected non-static data
members (clause 11), no base classes (clause 10), and no virtual functions
(10.3)."
And for sure, read the FAQ: http://www.parashift.com/c++-faq-lit....html#faq-26.7
Thanks all a lot for you input in this thread. I hope I got it now.
Kind regards,
Patrick
Hello Alf, For now, rename the orginal struct to PodA,
struct PodA { ... };
then derive struct A from that,
struct A: PodA { A(): PodA() {} std::vector<int> z; };
and also check that your compiler supports default-initialization of POD's (unfortunately some don't).
I checked this. Some of my compilers support default-initialization, some
not :(. This is really sad.
So I use now this here (even if there is a difference to memset in the
result):
struct A_PODs{ ... };
struct A : public A_PODs
{
A()
{
static A_PODs zero_init = { 0 };
// static A_PODs zero_init = { }; // would be enough, but does not
work on all compilers.
*(static_cast< A_PODs * >(this)) = zero_init; // is this safe?
}
};
Kind regards,
Patrick This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Joe C |
last post by:
I'm a hobbiest, and made the forray into c++ from non-c type languages about
a year ago. I was "cleaning up" some code I wrote to make it more "c++
like" and have a few questions. I'm comfortable...
|
by: Nollie |
last post by:
Say you have a struct:
struct MYSTRUCT
{
int x;
int y;
int w;
int h;
};
|
by: bob_jenkins |
last post by:
{
const void *p;
(void)memset((void *)p, ' ', (size_t)10);
}
Should this call to memset() be legal? Memset is of type
void *memset(void *, unsigned char, size_t)
Also, (void *) is the...
|
by: volunteers |
last post by:
I met a question about memset and have no idea right now. Could anybody
give a clue? Thanks
memset is sometimes used to initialize data in a constructor like the
example below. What is the...
|
by: dykeinthebox |
last post by:
Consider the following program:
#include <stdlib.h>
#include <string.h>
int main( void )
{
void *p = malloc( 4 );
if ( p )
{
|
by: JohnQ |
last post by:
Are a default constructor, destructor, copy constructor and assignment
operator generated by the compiler for a struct if they are not explicitely
defined?
I think the answer is yes, because...
|
by: JohnQ |
last post by:
The implementation of classes with virtual functions is conceptually easy to
understand: they use vtables. Which begs the question about POD structs: how
are they associated with their member...
|
by: Martin Wells |
last post by:
I'm trying to come up with a fully-portable macro for supplying memset
with an unsigned char rather than an int. I'm going to think out loud
as I go along. . .
I'll take a sample system before I...
|
by: Gaijinco |
last post by:
I'm having a headache using memset()
Given:
int v;
memset((void*)v, 1, sizeof(v));
Can I be 100% positive than v = 1 for i 0, or there is something
else I have to do?.
|
by: viza |
last post by:
Hi all
Is this assertion guaranteed?
{
void *vptr;
memset( & vptr, 0, sizeof vptr);
assert( NULL == vptr );
}
What about these ones?
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
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: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
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: 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...
|
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...
| |