Topic: structure pad bytes


Author: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/15
Raw View
In article <36E6495B.230BA2EE@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> AllanW@my-dejanews.com wrote:
> >
> > In article <7c2tkv$8l3$1@develop-help.com>,
> >   tony@develop-help.com (Tony Cook) wrote:
> > > AllanW@my-dejanews.com wrote:
> > > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > > : >
> > > : > Does the standard make any guarantees about the value of structure pad
> > > : > bytes?  I can't find anything about it from the index, but if not
then it
> > > : > seems like you could not even memcmp two POD's.

> > There are two ways to deal with this issue. The first method, perhaps the
> > more obvious is to ensure that the padding bytes are always set to a
> > known value. This can be done for POD without much difficulty:
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >         myData() {
> >             memset(this, '\0', sizeof(*this));
> >         }
> >     };
>
> Except that this is not a POD any more.
> PODs don't have constructors by definition.

The constructor does nothing except add automatic initialization.
As I mentioned in the next paragraph, this could also be done
manually via memset().

> > Here, the constructor initializes every byte of myData to null bytes.
> > (You could also do this "manually" in every place that creates a new
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > instance of myData, but this is bloated and error-prone.) After this,
> > you can copy 'real' data into the individual members and still use
> > memcpy() to compare two myData members.
>
> However, the standard AFAIK doesn't guarantee that it works - it's a
> non-POD, and with non-PODs the compiler may add extra fields at
> his will. It's quite unlikely that any compiler will do that with
> the above, but in theory, the compiler could silently add any other
> data it likes. For example, a debug version could add a "valid"
> field which is set to a special value on construction, and to
> anoth special valur on destruction, so the compiler can detect
> most uses of uninitialized or already destructed structs. Your
> code would break on that compiler.

Yes. Okay, version 3:
    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
    };
    void myData_PreInit(myData&m) { memset(&m, '\0', sizeof(m)); }

> With PODs, memset is safe (however, be aware that if you
> use pointers, setting all bytes to 0 isn't guaranteed to
> result in a null pointer).

And if you use float or double, that isn't guaranteed to be 0.0 either.
The point of the memset() isn't to initialize the data members, but to
initialize the padding bytes between the data members. Then normal
initialization takes place for everything else.

> > Note that if your data has C-style null-terminated strings (such as
> > myName, above), you must ensure that there is not any trailing garbage
> > after the null terminator.

Again, for purposes of memcmp() only. The following code breaks:
    myData d1, d2;
    myData_PreInit(d1);
    myData_PreInit(d2);
    strcpy(d1.myName, "This is a long name");
    strcpy(d2.myName, "ShortName");
    if (d1.myAge == d2.myAge) {
        strcpy(d1.myName, d2.myName);
        assert(0==memcmp(&d1, &d2, sizeof(d1))); // FAILS!
    }

Normally strcpy() is an acceptable way to load myName, but if we
plan to compare the structures with memcmp() we must use a different
technique, one that sets all 31 bytes to a known value rather than
terminating at the first \0 byte.

> > The second method, and in my opinion the superior one, is to use
> > alternatives to memcmp():
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >
> >         bool operator==(const myData&x) const {
> >             if (strcmp(myName, x.myName)) return false;
> >             if (myAge != x.myAge) return false;
> >             // ...
> >             return true;
> >         }
> >         bool operator<(const myData&x) const {
> >             int i=strcmp(myName, x.myName);
> >             if (i) return i<0;
> >             if (myAge != x.myAge) return myAge<x.myAge;
> >             // ...
> >             return false;
> >         }
> >         bool operator<=(const myData&x) const { return !(x<(*this));  }
> >         bool operator >(const myData&x) const { return   x<(*this);   }
> >         bool operator>=(const myData&x) const { return !((*this)<x);  }
> >         bool operator!=(const myData&x) const { return !((*this)==x); }
> >     };
>
> Here I agree completely. Moreover, this is guaranteed to work
> even for non-PODs.
> However, generally binary operators should be made global,
> so that conversions apply the same way for left and right
> hand arguments.

Matter of style. I usually do make these global, but this data was
originally POD. It's unlikely to be part of a class heirarchy, and
conversions would be rare.

----
Allan_W@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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/10
Raw View
AllanW@my-dejanews.com wrote:
>
> In article <7c2tkv$8l3$1@develop-help.com>,
>   tony@develop-help.com (Tony Cook) wrote:
> > AllanW@my-dejanews.com wrote:
> > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > : >
> > : > Does the standard make any guarantees about the value of structure pad
> > : > bytes?  I can't find anything about it from the index, but if not then it
> > : > seems like you could not even memcmp two POD's.
> >
> > : Why not? AFAIK, the structure pad bytes need not be initialized to
> > : anything. Since these bytes are (theoretically) never used for
> > : anything, their indeterminate state does no harm.
> >
> > : This does not prevent you from using memcmp to copy the entire
> > : structure (including uninitialized pad bytes) to another instance
> > : of the same structure. The fact that the values of these
> > : uninitialized bytes is preserved does no harm at all.
> >
> > I think you mis-read the original question.
> >
> > memcmp() is used for comparing blocks of memory, not copying them.
>
> Oops! You're right, I did. And I even typed memcmp instead of memcpy
> in my reply!
>
> > The effectively random data in the padding does have an effect on memcmp().
>
> Yes, it clearly does.
>
> Alright, take 2:
>
> There are two ways to deal with this issue. The first method, perhaps the
> more obvious is to ensure that the padding bytes are always set to a
> known value. This can be done for POD without much difficulty:
>
>     struct myData {
>         char    myName[31];
>         // Likely to be some padding here
>         long    myAge;
>         myData() {
>             memset(this, '\0', sizeof(*this));
>         }
>     };

Except that this is not a POD any more.
PODs don't have constructors by definition.

>
> Here, the constructor initializes every byte of myData to null bytes.
> (You could also do this "manually" in every place that creates a new
> instance of myData, but this is bloated and error-prone.) After this,
> you can copy 'real' data into the individual members and still use
> memcpy() to compare two myData members.

However, the standard AFAIK doesn't guarantee that it works - it's a
non-POD, and with non-PODs the compiler may add extra fields at
his will. It's quite unlikely that any compiler will do that with
the above, but in theory, the compiler could silently add any other
data it likes. For example, a debug version could add a "valid"
field which is set to a special value on construction, and to
anoth special valur on destruction, so the compiler can detect
most uses of uninitialized or already destructed structs. Your
code would break on that compiler.
With PODs, memset is safe (however, be aware that if you
use pointers, setting all bytes to 0 isn't guaranteed to
result in a null pointer).

>
> Note that if your data has C-style null-terminated strings (such as
> myName, above), you must ensure that there is not any trailing garbage
> after the null terminator.
>
> The second method, and in my opinion the superior one, is to use
> alternatives to memcmp():
>
>     struct myData {
>         char    myName[31];
>         // Likely to be some padding here
>         long    myAge;
>
>         bool operator==(const myData&x) const {
>             if (strcmp(myName, x.myName)) return false;
>             if (myAge != x.myAge) return false;
>             // ...
>             return true;
>         }
>         bool operator<(const myData&x) const {
>             int i=strcmp(myName, x.myName);
>             if (i) return i<0;
>             if (myAge != x.myAge) return myAge<x.myAge;
>             // ...
>             return false;
>         }
>         bool operator<=(const myData&x) const { return !(x<(*this));  }
>         bool operator >(const myData&x) const { return   x<(*this);   }
>         bool operator>=(const myData&x) const { return !((*this)<x);  }
>         bool operator!=(const myData&x) const { return !((*this)==x); }
>     };

Here I agree completely. Moreover, this is guaranteed to work
even for non-PODs.
However, generally binary operators should be made global,
so that conversions apply the same way for left and right
hand arguments.

>
> Now instead of
>     if (memcmp(a,b,sizeof(a))<0) { /* ... */ }
> you can use
>     if (a<b) { /* ... */ }
> Note also that I used strcmp() instead of memcmp(). This means that
> the restriction on data after the null terminator no longer applies.
>
> The comparisons don't have to be done in member functions, of course.
> It can be done anywhere, provided we compare one member at a time.
> However, the methods above are perhaps the most clear, since they
> allow us to write expressions as if myData was a built-in type.

The same is true for global operator<(MyData const&, MyData const&)

Defining an operator< also enables the use of the class in
associative containers like sets and maps.


[ 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@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/13
Raw View
In article <36E6495B.230BA2EE@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> AllanW@my-dejanews.com wrote:
> >
> > In article <7c2tkv$8l3$1@develop-help.com>,
> >   tony@develop-help.com (Tony Cook) wrote:
> > > AllanW@my-dejanews.com wrote:
> > > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > > : >
> > > : > Does the standard make any guarantees about the value of structure pad
> > > : > bytes?  I can't find anything about it from the index, but if not
then it
> > > : > seems like you could not even memcmp two POD's.
> > >
> > > : Why not? AFAIK, the structure pad bytes need not be initialized to
> > > : anything. Since these bytes are (theoretically) never used for
> > > : anything, their indeterminate state does no harm.
> > >
> > > : This does not prevent you from using memcmp to copy the entire
> > > : structure (including uninitialized pad bytes) to another instance
> > > : of the same structure. The fact that the values of these
> > > : uninitialized bytes is preserved does no harm at all.
> > >
> > > I think you mis-read the original question.
> > >
> > > memcmp() is used for comparing blocks of memory, not copying them.
> >
> > Oops! You're right, I did. And I even typed memcmp instead of memcpy
> > in my reply!
> >
> > > The effectively random data in the padding does have an effect on memcmp
().
> >
> > Yes, it clearly does.
> >
> > Alright, take 2:
> >
> > There are two ways to deal with this issue. The first method, perhaps the
> > more obvious is to ensure that the padding bytes are always set to a
> > known value. This can be done for POD without much difficulty:
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >         myData() {
> >             memset(this, '\0', sizeof(*this));
> >         }
> >     };
>
> Except that this is not a POD any more.
> PODs don't have constructors by definition.

The constructor does nothing except add automatic initialization.
As I mentioned in the next paragraph, this could also be done
manually via memset().

> > Here, the constructor initializes every byte of myData to null bytes.
> > (You could also do this "manually" in every place that creates a new
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > instance of myData, but this is bloated and error-prone.) After this,
> > you can copy 'real' data into the individual members and still use
> > memcpy() to compare two myData members.
>
> However, the standard AFAIK doesn't guarantee that it works - it's a
> non-POD, and with non-PODs the compiler may add extra fields at
> his will. It's quite unlikely that any compiler will do that with
> the above, but in theory, the compiler could silently add any other
> data it likes. For example, a debug version could add a "valid"
> field which is set to a special value on construction, and to
> anoth special valur on destruction, so the compiler can detect
> most uses of uninitialized or already destructed structs. Your
> code would break on that compiler.

Yes. Okay, version 3:
    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
    };
    void myData_PreInit(myData&m) { memset(&m, '\0', sizeof(m)); }

> With PODs, memset is safe (however, be aware that if you
> use pointers, setting all bytes to 0 isn't guaranteed to
> result in a null pointer).

And if you use float or double, that isn't guaranteed to be 0.0 either.
The point of the memset() isn't to initialize the data members, but to
initialize the padding bytes between the data members. Then normal
initialization takes place for everything else.

> > Note that if your data has C-style null-terminated strings (such as
> > myName, above), you must ensure that there is not any trailing garbage
> > after the null terminator.

Again, for purposes of memcmp() only. The following code breaks:
    myData d1, d2;
    myData_PreInit(d1);
    myData_PreInit(d2);
    strcpy(d1.myName, "This is a long name");
    strcpy(d2.myName, "ShortName");
    if (d1.myAge == d2.myAge) {
        strcpy(d1.myName, d2.myName);
        assert(0==memcmp(&d1, &d2, sizeof(d1))); // FAILS!
    }

Normally strcpy() is an acceptable way to load myName, but if we
plan to compare the structures with memcmp() we must use a different
technique, one that sets all 31 bytes to a known value rather than
terminating at the first \0 byte.

> > The second method, and in my opinion the superior one, is to use
> > alternatives to memcmp():
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >
> >         bool operator==(const myData&x) const {
> >             if (strcmp(myName, x.myName)) return false;
> >             if (myAge != x.myAge) return false;
> >             // ...
> >             return true;
> >         }
> >         bool operator<(const myData&x) const {
> >             int i=strcmp(myName, x.myName);
> >             if (i) return i<0;
> >             if (myAge != x.myAge) return myAge<x.myAge;
> >             // ...
> >             return false;
> >         }
> >         bool operator<=(const myData&x) const { return !(x<(*this));  }
> >         bool operator >(const myData&x) const { return   x<(*this);   }
> >         bool operator>=(const myData&x) const { return !((*this)<x);  }
> >         bool operator!=(const myData&x) const { return !((*this)==x); }
> >     };
>
> Here I agree completely. Moreover, this is guaranteed to work
> even for non-PODs.
> However, generally binary operators should be made global,
> so that conversions apply the same way for left and right
> hand arguments.

Matter of style. I usually do make these global, but this data was
originally POD. It's unlikely to be part of a class heirarchy, and
conversions would be rare.

> > Now instead of
> >     if (memcmp(a,b,sizeof(a))<0) { /* ... */ }
> > you can use
> >     if (a<b) { /* ... */ }
> > Note also that I used strcmp() instead of memcmp(). This means that
> > the restriction on data after the null terminator no longer applies.
> >
> > The comparisons don't have to be done in member functions, of course.
> > It can be done anywhere, provided we compare one member at a time.
> > However, the methods above are perhaps the most clear, since they
> > allow us to write expressions as if myData was a built-in type.
>
> The same is true for global operator<(MyData const&, MyData const&)

As I just said.

> Defining an operator< also enables the use of the class in
> associative containers like sets and maps.

Right.

----
Allan_W@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: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/13
Raw View
In article <36E6495B.230BA2EE@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> AllanW@my-dejanews.com wrote:
> >
> > In article <7c2tkv$8l3$1@develop-help.com>,
> >   tony@develop-help.com (Tony Cook) wrote:
> > > AllanW@my-dejanews.com wrote:
> > > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > > : >
> > > : > Does the standard make any guarantees about the value of structure pad
> > > : > bytes?  I can't find anything about it from the index, but if not
then it
> > > : > seems like you could not even memcmp two POD's.
> > >
> > > : Why not? AFAIK, the structure pad bytes need not be initialized to
> > > : anything. Since these bytes are (theoretically) never used for
> > > : anything, their indeterminate state does no harm.
> > >
> > > : This does not prevent you from using memcmp to copy the entire
> > > : structure (including uninitialized pad bytes) to another instance
> > > : of the same structure. The fact that the values of these
> > > : uninitialized bytes is preserved does no harm at all.
> > >
> > > I think you mis-read the original question.
> > >
> > > memcmp() is used for comparing blocks of memory, not copying them.
> >
> > Oops! You're right, I did. And I even typed memcmp instead of memcpy
> > in my reply!
> >
> > > The effectively random data in the padding does have an effect on memcmp
().
> >
> > Yes, it clearly does.
> >
> > Alright, take 2:
> >
> > There are two ways to deal with this issue. The first method, perhaps the
> > more obvious is to ensure that the padding bytes are always set to a
> > known value. This can be done for POD without much difficulty:
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >         myData() {
> >             memset(this, '\0', sizeof(*this));
> >         }
> >     };
>
> Except that this is not a POD any more.
> PODs don't have constructors by definition.

The constructor does nothing except add automatic initialization.
As I mentioned in the next paragraph, this could also be done
manually via memset().

> > Here, the constructor initializes every byte of myData to null bytes.
> > (You could also do this "manually" in every place that creates a new
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > instance of myData, but this is bloated and error-prone.) After this,
> > you can copy 'real' data into the individual members and still use
> > memcpy() to compare two myData members.
>
> However, the standard AFAIK doesn't guarantee that it works - it's a
> non-POD, and with non-PODs the compiler may add extra fields at
> his will. It's quite unlikely that any compiler will do that with
> the above, but in theory, the compiler could silently add any other
> data it likes. For example, a debug version could add a "valid"
> field which is set to a special value on construction, and to
> anoth special valur on destruction, so the compiler can detect
> most uses of uninitialized or already destructed structs. Your
> code would break on that compiler.

Yes. Okay, version 3:
    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
    };
    void myData_PreInit(myData&m) { memset(&m, '\0', sizeof(m)); }

> With PODs, memset is safe (however, be aware that if you
> use pointers, setting all bytes to 0 isn't guaranteed to
> result in a null pointer).

And if you use float or double, that isn't guaranteed to be 0.0 either.
The point of the memset() isn't to initialize the data members, but to
initialize the padding bytes between the data members. Then normal
initialization takes place for everything else.

> > Note that if your data has C-style null-terminated strings (such as
> > myName, above), you must ensure that there is not any trailing garbage
> > after the null terminator.

Again, for purposes of memcmp() only. The following code breaks:
    myData d1, d2;
    myData_PreInit(d1);
    myData_PreInit(d2);
    strcpy(d1.myName, "This is a long name");
    strcpy(d2.myName, "ShortName");
    if (d1.myAge == d2.myAge) {
        strcpy(d1.myName, d2.myName);
        assert(0==memcmp(&d1, &d2, sizeof(d1))); // FAILS!
    }

Normally strcpy() is an acceptable way to load myName, but if we
plan to compare the structures with memcmp() we must use a different
technique, one that sets all 31 bytes to a known value rather than
terminating at the first \0 byte.

> > The second method, and in my opinion the superior one, is to use
> > alternatives to memcmp():
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >
> >         bool operator==(const myData&x) const {
> >             if (strcmp(myName, x.myName)) return false;
> >             if (myAge != x.myAge) return false;
> >             // ...
> >             return true;
> >         }
> >         bool operator<(const myData&x) const {
> >             int i=strcmp(myName, x.myName);
> >             if (i) return i<0;
> >             if (myAge != x.myAge) return myAge<x.myAge;
> >             // ...
> >             return false;
> >         }
> >         bool operator<=(const myData&x) const { return !(x<(*this));  }
> >         bool operator >(const myData&x) const { return   x<(*this);   }
> >         bool operator>=(const myData&x) const { return !((*this)<x);  }
> >         bool operator!=(const myData&x) const { return !((*this)==x); }
> >     };
>
> Here I agree completely. Moreover, this is guaranteed to work
> even for non-PODs.
> However, generally binary operators should be made global,
> so that conversions apply the same way for left and right
> hand arguments.

Matter of style. I usually do make these global, but this data was
originally POD. It's unlikely to be part of a class heirarchy, and
conversions would be rare.

> > Now instead of
> >     if (memcmp(a,b,sizeof(a))<0) { /* ... */ }
> > you can use
> >     if (a<b) { /* ... */ }
> > Note also that I used strcmp() instead of memcmp(). This means that
> > the restriction on data after the null terminator no longer applies.
> >
> > The comparisons don't have to be done in member functions, of course.
> > It can be done anywhere, provided we compare one member at a time.
> > However, the methods above are perhaps the most clear, since they
> > allow us to write expressions as if myData was a built-in type.
>
> The same is true for global operator<(MyData const&, MyData const&)

As I just said.

> Defining an operator< also enables the use of the class in
> associative containers like sets and maps.

Right.

----
Allan_W@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: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/13
Raw View
In article <36E6495B.230BA2EE@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> AllanW@my-dejanews.com wrote:
> >
> > In article <7c2tkv$8l3$1@develop-help.com>,
> >   tony@develop-help.com (Tony Cook) wrote:
> > > AllanW@my-dejanews.com wrote:
> > > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > > : >
> > > : > Does the standard make any guarantees about the value of structure pad
> > > : > bytes?  I can't find anything about it from the index, but if not
then it
> > > : > seems like you could not even memcmp two POD's.
> > >
> > > : Why not? AFAIK, the structure pad bytes need not be initialized to
> > > : anything. Since these bytes are (theoretically) never used for
> > > : anything, their indeterminate state does no harm.
> > >
> > > : This does not prevent you from using memcmp to copy the entire
> > > : structure (including uninitialized pad bytes) to another instance
> > > : of the same structure. The fact that the values of these
> > > : uninitialized bytes is preserved does no harm at all.
> > >
> > > I think you mis-read the original question.
> > >
> > > memcmp() is used for comparing blocks of memory, not copying them.
> >
> > Oops! You're right, I did. And I even typed memcmp instead of memcpy
> > in my reply!
> >
> > > The effectively random data in the padding does have an effect on memcmp
().
> >
> > Yes, it clearly does.
> >
> > Alright, take 2:
> >
> > There are two ways to deal with this issue. The first method, perhaps the
> > more obvious is to ensure that the padding bytes are always set to a
> > known value. This can be done for POD without much difficulty:
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >         myData() {
> >             memset(this, '\0', sizeof(*this));
> >         }
> >     };
>
> Except that this is not a POD any more.
> PODs don't have constructors by definition.

The constructor does nothing except add automatic initialization.
As I mentioned in the next paragraph, this could also be done
manually via memset().

> > Here, the constructor initializes every byte of myData to null bytes.
> > (You could also do this "manually" in every place that creates a new
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > instance of myData, but this is bloated and error-prone.) After this,
> > you can copy 'real' data into the individual members and still use
> > memcpy() to compare two myData members.
>
> However, the standard AFAIK doesn't guarantee that it works - it's a
> non-POD, and with non-PODs the compiler may add extra fields at
> his will. It's quite unlikely that any compiler will do that with
> the above, but in theory, the compiler could silently add any other
> data it likes. For example, a debug version could add a "valid"
> field which is set to a special value on construction, and to
> anoth special valur on destruction, so the compiler can detect
> most uses of uninitialized or already destructed structs. Your
> code would break on that compiler.

Yes. Okay, version 3:
    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
    };
    void myData_PreInit(myData&m) { memset(&m, '\0', sizeof(m)); }

> With PODs, memset is safe (however, be aware that if you
> use pointers, setting all bytes to 0 isn't guaranteed to
> result in a null pointer).

And if you use float or double, that isn't guaranteed to be 0.0 either.
The point of the memset() isn't to initialize the data members, but to
initialize the padding bytes between the data members. Then normal
initialization takes place for everything else.

> > Note that if your data has C-style null-terminated strings (such as
> > myName, above), you must ensure that there is not any trailing garbage
> > after the null terminator.

Again, for purposes of memcmp() only. The following code breaks:
    myData d1, d2;
    myData_PreInit(d1);
    myData_PreInit(d2);
    strcpy(d1.myName, "This is a long name");
    strcpy(d2.myName, "ShortName");
    if (d1.myAge == d2.myAge) {
        strcpy(d1.myName, d2.myName);
        assert(0==memcmp(&d1, &d2, sizeof(d1))); // FAILS!
    }

Normally strcpy() is an acceptable way to load myName, but if we
plan to compare the structures with memcmp() we must use a different
technique, one that sets all 31 bytes to a known value rather than
terminating at the first \0 byte.

> > The second method, and in my opinion the superior one, is to use
> > alternatives to memcmp():
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >
> >         bool operator==(const myData&x) const {
> >             if (strcmp(myName, x.myName)) return false;
> >             if (myAge != x.myAge) return false;
> >             // ...
> >             return true;
> >         }
> >         bool operator<(const myData&x) const {
> >             int i=strcmp(myName, x.myName);
> >             if (i) return i<0;
> >             if (myAge != x.myAge) return myAge<x.myAge;
> >             // ...
> >             return false;
> >         }
> >         bool operator<=(const myData&x) const { return !(x<(*this));  }
> >         bool operator >(const myData&x) const { return   x<(*this);   }
> >         bool operator>=(const myData&x) const { return !((*this)<x);  }
> >         bool operator!=(const myData&x) const { return !((*this)==x); }
> >     };
>
> Here I agree completely. Moreover, this is guaranteed to work
> even for non-PODs.
> However, generally binary operators should be made global,
> so that conversions apply the same way for left and right
> hand arguments.

Matter of style. I usually do make these global, but this data was
originally POD. It's unlikely to be part of a class heirarchy, and
conversions would be rare.

> > Now instead of
> >     if (memcmp(a,b,sizeof(a))<0) { /* ... */ }
> > you can use
> >     if (a<b) { /* ... */ }
> > Note also that I used strcmp() instead of memcmp(). This means that
> > the restriction on data after the null terminator no longer applies.
> >
> > The comparisons don't have to be done in member functions, of course.
> > It can be done anywhere, provided we compare one member at a time.
> > However, the methods above are perhaps the most clear, since they
> > allow us to write expressions as if myData was a built-in type.
>
> The same is true for global operator<(MyData const&, MyData const&)

As I just said.

> Defining an operator< also enables the use of the class in
> associative containers like sets and maps.

Right.

----
Allan_W@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: AllanW@dejanews.com (formerly AllanW@my-dejanews.com <allan_w@my-dejanews.com>)
Date: 1999/03/13
Raw View
In article <36E6495B.230BA2EE@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> AllanW@my-dejanews.com wrote:
> >
> > In article <7c2tkv$8l3$1@develop-help.com>,
> >   tony@develop-help.com (Tony Cook) wrote:
> > > AllanW@my-dejanews.com wrote:
> > > : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> > > :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> > > : >
> > > : > Does the standard make any guarantees about the value of structure pad
> > > : > bytes?  I can't find anything about it from the index, but if not
then it
> > > : > seems like you could not even memcmp two POD's.

> > There are two ways to deal with this issue. The first method, perhaps the
> > more obvious is to ensure that the padding bytes are always set to a
> > known value. This can be done for POD without much difficulty:
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >         myData() {
> >             memset(this, '\0', sizeof(*this));
> >         }
> >     };
>
> Except that this is not a POD any more.
> PODs don't have constructors by definition.

The constructor does nothing except add automatic initialization.
As I mentioned in the next paragraph, this could also be done
manually via memset().

> > Here, the constructor initializes every byte of myData to null bytes.
> > (You could also do this "manually" in every place that creates a new
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > instance of myData, but this is bloated and error-prone.) After this,
> > you can copy 'real' data into the individual members and still use
> > memcpy() to compare two myData members.
>
> However, the standard AFAIK doesn't guarantee that it works - it's a
> non-POD, and with non-PODs the compiler may add extra fields at
> his will. It's quite unlikely that any compiler will do that with
> the above, but in theory, the compiler could silently add any other
> data it likes. For example, a debug version could add a "valid"
> field which is set to a special value on construction, and to
> anoth special valur on destruction, so the compiler can detect
> most uses of uninitialized or already destructed structs. Your
> code would break on that compiler.

Yes. Okay, version 3:
    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
    };
    void myData_PreInit(myData&m) { memset(&m, '\0', sizeof(m)); }

> With PODs, memset is safe (however, be aware that if you
> use pointers, setting all bytes to 0 isn't guaranteed to
> result in a null pointer).

And if you use float or double, that isn't guaranteed to be 0.0 either.
The point of the memset() isn't to initialize the data members, but to
initialize the padding bytes between the data members. Then normal
initialization takes place for everything else.

> > Note that if your data has C-style null-terminated strings (such as
> > myName, above), you must ensure that there is not any trailing garbage
> > after the null terminator.

Again, for purposes of memcmp() only. The following code breaks:
    myData d1, d2;
    myData_PreInit(d1);
    myData_PreInit(d2);
    strcpy(d1.myName, "This is a long name");
    strcpy(d2.myName, "ShortName");
    if (d1.myAge == d2.myAge) {
        strcpy(d1.myName, d2.myName);
        assert(0==memcmp(&d1, &d2, sizeof(d1))); // FAILS!
    }

Normally strcpy() is an acceptable way to load myName, but if we
plan to compare the structures with memcmp() we must use a different
technique, one that sets all 31 bytes to a known value rather than
terminating at the first \0 byte.

> > The second method, and in my opinion the superior one, is to use
> > alternatives to memcmp():
> >
> >     struct myData {
> >         char    myName[31];
> >         // Likely to be some padding here
> >         long    myAge;
> >
> >         bool operator==(const myData&x) const {
> >             if (strcmp(myName, x.myName)) return false;
> >             if (myAge != x.myAge) return false;
> >             // ...
> >             return true;
> >         }
> >         bool operator<(const myData&x) const {
> >             int i=strcmp(myName, x.myName);
> >             if (i) return i<0;
> >             if (myAge != x.myAge) return myAge<x.myAge;
> >             // ...
> >             return false;
> >         }
> >         bool operator<=(const myData&x) const { return !(x<(*this));  }
> >         bool operator >(const myData&x) const { return   x<(*this);   }
> >         bool operator>=(const myData&x) const { return !((*this)<x);  }
> >         bool operator!=(const myData&x) const { return !((*this)==x); }
> >     };
>
> Here I agree completely. Moreover, this is guaranteed to work
> even for non-PODs.
> However, generally binary operators should be made global,
> so that conversions apply the same way for left and right
> hand arguments.

Matter of style. I usually do make these global, but this data was
originally POD. It's unlikely to be part of a class heirarchy, and
conversions would be rare.

----
Allan_W@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: tony@develop-help.com (Tony Cook)
Date: 1999/03/09
Raw View
AllanW@my-dejanews.com wrote:
: In article <7bt74e$kbh$1@camel29.mindspring.com>,
:   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
: >
: > Does the standard make any guarantees about the value of structure pad
: > bytes?  I can't find anything about it from the index, but if not then it
: > seems like you could not even memcmp two POD's.

: Why not? AFAIK, the structure pad bytes need not be initialized to
: anything. Since these bytes are (theoretically) never used for
: anything, their indeterminate state does no harm.

: This does not prevent you from using memcmp to copy the entire
: structure (including uninitialized pad bytes) to another instance
: of the same structure. The fact that the values of these
: uninitialized bytes is preserved does no harm at all.

I think you mis-read the original question.

memcmp() is used for comparing blocks of memory, not copying them.

The effectively random data in the padding does have an effect on memcmp().
---
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/09
Raw View
AllanW@my-dejanews.com wrote:
>
> In article <7bt74e$kbh$1@camel29.mindspring.com>,
>   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> >
> > Does the standard make any guarantees about the value of structure pad
> > bytes?  I can't find anything about it from the index, but if not then it
> > seems like you could not even memcmp two POD's.
>
> Why not? AFAIK, the structure pad bytes need not be initialized to
> anything. Since these bytes are (theoretically) never used for
> anything, their indeterminate state does no harm.
>
> This does not prevent you from using memcmp to copy the entire
> structure (including uninitialized pad bytes) to another instance
> of the same structure. The fact that the values of these
> uninitialized bytes is preserved does no harm at all.

He spoke about memcmp, not memcpy. And given the two PODs

struct X { int a, char b };

X a = { 3, 'A' };
X b = { 3, 'A' };

int main()
{
  assert(memcmp(&a, &b, sizeof(a)) == 0);
}

may fail, because the padding bytes are not guaranteed
to be equal.


[ 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: 1999/03/09
Raw View
AllanW@my-dejanews.com wrote:
>
> In article <7bt74e$kbh$1@camel29.mindspring.com>,
>   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> >
> > Does the standard make any guarantees about the value of structure pad
> > bytes?  I can't find anything about it from the index, but if not then it
> > seems like you could not even memcmp two POD's.
>
> Why not? AFAIK, the structure pad bytes need not be initialized to
> anything. Since these bytes are (theoretically) never used for
> anything, their indeterminate state does no harm.
>
> This does not prevent you from using memcmp to copy the entire
> structure (including uninitialized pad bytes) to another instance
> of the same structure. The fact that the values of these
> uninitialized bytes is preserved does no harm at all.

That's memcmp(), not memcpy(). The padding bits make a big difference to
memcmp().


[ 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: Paul Black <paul@canix.co.uk>
Date: 1999/03/09
Raw View
AllanW@my-dejanews.com wrote:
>
> In article <7bt74e$kbh$1@camel29.mindspring.com>,
>   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> >
> > Does the standard make any guarantees about the value of structure pad
> > bytes?  I can't find anything about it from the index, but if not then it
> > seems like you could not even memcmp two POD's.
>
> Why not? AFAIK, the structure pad bytes need not be initialized to
> anything. Since these bytes are (theoretically) never used for
> anything, their indeterminate state does no harm.
>
> This does not prevent you from using memcmp to copy the entire
> structure (including uninitialized pad bytes) to another instance
> of the same structure. The fact that the values of these
> uninitialized bytes is preserved does no harm at all.

You appear to have mistaken compare for copy.

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: "Jonathan H Lundquist" <fluxsmith@fluxsmith.com>
Date: 1999/03/09
Raw View
I was referring to memcmp, not memcpy.  I think it would come as a surprise
to many that you really can't memcmp two POD's.

<AllanW@my-dejanews.com> wrote in message
news:7c1ukk$7dm$1@nnrp1.dejanews.com...
>In article <7bt74e$kbh$1@camel29.mindspring.com>,
>  "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
>>
>> Does the standard make any guarantees about the value of structure pad
>> bytes?  I can't find anything about it from the index, but if not then it
>> seems like you could not even memcmp two POD's.
>
>Why not? AFAIK, the structure pad bytes need not be initialized to
>anything. Since these bytes are (theoretically) never used for
>anything, their indeterminate state does no harm.
>
>This does not prevent you from using memcmp to copy the entire
>structure (including uninitialized pad bytes) to another instance
>of the same structure. The fact that the values of these
>uninitialized bytes is preserved does no harm at all.

[ moderator's note: excessive quoting removed. -sdc ]



[ 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: "Ross Smith" <ross.s@ihug.co.nz>
Date: 1999/03/09
Raw View
AllanW@my-dejanews.com wrote in message <7c1ukk$7dm$1@nnrp1.dejanews.com>...
>In article <7bt74e$kbh$1@camel29.mindspring.com>,
>  "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
>>
>> Does the standard make any guarantees about the value of structure pad
>> bytes?  I can't find anything about it from the index, but if not then it
>> seems like you could not even memcmp two POD's.
>
>Why not? AFAIK, the structure pad bytes need not be initialized to
>anything. Since these bytes are (theoretically) never used for
>anything, their indeterminate state does no harm.
>
>This does not prevent you from using memcmp to copy the entire
>structure (including uninitialized pad bytes) to another instance
>of the same structure. The fact that the values of these
>uninitialized bytes is preserved does no harm at all.

He's talking about comparisons (memcmp); you're confusing it with
copying (memcpy/memmove). He's right, you can't reliably use memcmp on
structures.

--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
         "The award for the Most Effective Promotion of Linux
         goes to Microsoft."             -- Nicholas Petreley



[ 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: 1999/03/09
Raw View
In article <7c2tkv$8l3$1@develop-help.com>,
  tony@develop-help.com (Tony Cook) wrote:
> AllanW@my-dejanews.com wrote:
> : In article <7bt74e$kbh$1@camel29.mindspring.com>,
> :   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> : >
> : > Does the standard make any guarantees about the value of structure pad
> : > bytes?  I can't find anything about it from the index, but if not then it
> : > seems like you could not even memcmp two POD's.
>
> : Why not? AFAIK, the structure pad bytes need not be initialized to
> : anything. Since these bytes are (theoretically) never used for
> : anything, their indeterminate state does no harm.
>
> : This does not prevent you from using memcmp to copy the entire
> : structure (including uninitialized pad bytes) to another instance
> : of the same structure. The fact that the values of these
> : uninitialized bytes is preserved does no harm at all.
>
> I think you mis-read the original question.
>
> memcmp() is used for comparing blocks of memory, not copying them.

Oops! You're right, I did. And I even typed memcmp instead of memcpy
in my reply!

> The effectively random data in the padding does have an effect on memcmp().

Yes, it clearly does.

Alright, take 2:

There are two ways to deal with this issue. The first method, perhaps the
more obvious is to ensure that the padding bytes are always set to a
known value. This can be done for POD without much difficulty:

    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;
        myData() {
            memset(this, '\0', sizeof(*this));
        }
    };

Here, the constructor initializes every byte of myData to null bytes.
(You could also do this "manually" in every place that creates a new
instance of myData, but this is bloated and error-prone.) After this,
you can copy 'real' data into the individual members and still use
memcpy() to compare two myData members.

Note that if your data has C-style null-terminated strings (such as
myName, above), you must ensure that there is not any trailing garbage
after the null terminator.

The second method, and in my opinion the superior one, is to use
alternatives to memcmp():

    struct myData {
        char    myName[31];
        // Likely to be some padding here
        long    myAge;

        bool operator==(const myData&x) const {
            if (strcmp(myName, x.myName)) return false;
            if (myAge != x.myAge) return false;
            // ...
            return true;
        }
        bool operator<(const myData&x) const {
            int i=strcmp(myName, x.myName);
            if (i) return i<0;
            if (myAge != x.myAge) return myAge<x.myAge;
            // ...
            return false;
        }
        bool operator<=(const myData&x) const { return !(x<(*this));  }
        bool operator >(const myData&x) const { return   x<(*this);   }
        bool operator>=(const myData&x) const { return !((*this)<x);  }
        bool operator!=(const myData&x) const { return !((*this)==x); }
    };

Now instead of
    if (memcmp(a,b,sizeof(a))<0) { /* ... */ }
you can use
    if (a<b) { /* ... */ }
Note also that I used strcmp() instead of memcmp(). This means that
the restriction on data after the null terminator no longer applies.

The comparisons don't have to be done in member functions, of course.
It can be done anywhere, provided we compare one member at a time.
However, the methods above are perhaps the most clear, since they
allow us to write expressions as if myData was a built-in type.

----
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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/03/09
Raw View
In article <7c1ukk$7dm$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com
writes
>This does not prevent you from using memcmp to copy the entire
>structure (including uninitialized pad bytes) to another instance
>of the same structure. The fact that the values of these
>uninitialized bytes is preserved does no harm at all.

He wrote (as did you) memcmp NOT memcpy


Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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.Kanze@dresdner-bank.com
Date: 1999/03/09
Raw View
In article <7c1ukk$7dm$1@nnrp1.dejanews.com>,
  AllanW@my-dejanews.com wrote:
> In article <7bt74e$kbh$1@camel29.mindspring.com>,
>   "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
> >
> > Does the standard make any guarantees about the value of structure pad
> > bytes?  I can't find anything about it from the index, but if not then it
> > seems like you could not even memcmp two POD's.
>
> Why not? AFAIK, the structure pad bytes need not be initialized to
> anything. Since these bytes are (theoretically) never used for
> anything, their indeterminate state does no harm.
>
> This does not prevent you from using memcmp to copy the entire
> structure (including uninitialized pad bytes) to another instance
> of the same structure. The fact that the values of these
> uninitialized bytes is preserved does no harm at all.

More importantly, memcpy (and accesses via unsigned char*) have a
special exemption, which means that accessing uninitialized memory is
not undefined behavior.

--
James Kanze                         mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                              Beratung in industrieller Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany    Tel. +49 (069) 263 17946

-----------== 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: "Jonathan H Lundquist" <fluxsmith@fluxsmith.com>
Date: 1999/03/07
Raw View
Does the standard make any guarantees about the value of structure pad
bytes?  I can't find anything about it from the index, but if not then it
seems like you could not even memcmp two POD's.



[ 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: Stephen.Clamage@sun.com (Steve Clamage)
Date: 1999/03/07
Raw View
"Jonathan H Lundquist" <fluxsmith@fluxsmith.com> writes:

>Does the standard make any guarantees about the value of structure pad
>bytes?

None at all.

>I can't find anything about it from the index, but if not then it
>seems like you could not even memcmp two POD's.

Correct. You should not depend on the contents of padding bytes
when comparing two structs. The same is true in C, by the way.

--
Steve Clamage, stephen.clamage@sun.com


[ 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: 1999/03/09
Raw View
In article <7bt74e$kbh$1@camel29.mindspring.com>,
  "Jonathan H Lundquist" <fluxsmith@fluxsmith.com> wrote:
>
> Does the standard make any guarantees about the value of structure pad
> bytes?  I can't find anything about it from the index, but if not then it
> seems like you could not even memcmp two POD's.

Why not? AFAIK, the structure pad bytes need not be initialized to
anything. Since these bytes are (theoretically) never used for
anything, their indeterminate state does no harm.

This does not prevent you from using memcmp to copy the entire
structure (including uninitialized pad bytes) to another instance
of the same structure. The fact that the values of these
uninitialized bytes is preserved does no harm at all.

----
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              ]