Ioannis said:
We can access an int, because int is a *POD type* and the standard
guarantees that we can create *exact copies* of any POD type and access
them via a pointer or reference of the POD type.
Built in types *are* POD types.
Actually the standard states:
"2. For any object (other than a base-class subobject) of POD type T,
whether or not the object holds a valid value of type T, the underlying
bytes (1.7) making up the object can be copied into an array of char or
unsigned char.36) If the content of the array of char or unsigned char
is copied back into the object, the object shall subsequently hold its
original value.
[Example:
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
memcpy(buf, &obj, N); // between these two calls to memcpy,
// obj might be modified
memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar
// type
// holds its original value
—end example]
3. For any POD type T, if two pointers to T point to distinct T objects
obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if
the value of obj1 is copied into obj2, using the memcpy library
function, obj2 shall subsequently hold the same value as obj1. [Example:
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
memcpy(t1p, t2p, sizeof(T)); // at this point, every subobject of POD
// type in *t1p contains
// the same value as the corresponding subobject in *t2p
—end example]
4. The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals
sizeof(T). The value representation of an object is the set of bits
that hold the value of type T. For POD types, the value representation
is a set of bits in the object representation that determines a value,
which is one discrete element of an implementation-defined set of values.37)
5. Object types have alignment requirements (3.9.1, 3.9.2). The
alignment of a complete object type is an implementation-defined integer
value representing a number of bytes; an object is allocated at an
address that meets the alignment requirements of its object type."
Unfortunately you are right.
Case 3:
At first the destination must be a pointer of the same object type (and
presumably the allocated space must be for the same type objects.
Secondly, the standard guarantees that only memcpy() works in this case,
and not copying it char by char or unsigned char by unsigned char. In
other words, in an implementation memcpy() can be defined in some exotic
way (e.g. assembly), and still copying it unsigned char by unsigned char
to the destination has undefined behaviour, while using memcpy() for the
same destination is guaranteed to work!
So my examples fixed (and not producing exactly the same results):
#include <iostream>
#include <cstring>
int main()
{
using namespace std;
int integer=4;
int secondInteger;
memcpy(&secondInteger, &integer, sizeof(integer));
cout<<integer<<"\n";
}
and
#include <iostream>
#include <cstring>
int main()
{
using namespace std;
int arrayInt[4]={1,2,3,4};
int secondArrayInt[sizeof(arrayInt)];
memcpy(secondArrayInt, arrayInt, sizeof(arrayInt));
for(unsigned i=0; i< sizeof(4); ++i)
cout<<secondArrayInt
<<"\n";
}
Please correct if I am wrong. Aren't the above guaranteed to be portable?