473,699 Members | 2,323 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Casting a byte array to allow assignment

I found the following code floating around somewhere and I'd like to
get some comments.

unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};

*(unsigned int *)a1=*(unsigned int *)a2;

// now a1[0]=a2[0], a1[1]=a2[1], etc.

This is taking a byte array, casting it to a 4 byte integer pointer,
then dereferencing it, then assigning it. This results in the contents
of array a1 copied to array a2. (corrections to my interpretation
welcome)

I don't know why this was done this way. My first instinct would have
been to use memcpy. Is this faster than memcpy? Are there any dangers
other than the potential for int not being 4 bytes?

Jul 24 '06
20 3513
On Mon, 24 Jul 2006 12:58:09 GMT, Frederick Gotham
<fg*******@SPAM .comwrote in comp.lang.c:
quantumred posted:
unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};

*(unsigned int *)a1=*(unsigned int *)a2;


This will work perfectly if:

(1) 4 == sizeof(int)

(2) alignof(char[4]) >= alignof(int)
The C Standard does not provide these guarantees for all platforms and
implementations . What you have is non-portable, platform-specific code.
To be perfectly correct, the C standard does not provide these
guarantees for ANY platform OR implementation.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 25 '06 #11

"Ben Pfaff" <bl*@cs.stanfor d.eduha scritto nel messaggio
news:87******** ****@benpfaff.o rg...
Frederick Gotham <fg*******@SPAM .comwrites:
quantumred posted:
unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};

*(unsigned int *)a1=*(unsigned int *)a2;
This will work perfectly if:

(1) 4 == sizeof(int)

(2) alignof(char[4]) >= alignof(int)

(3) unsigned int does not have trap representations , etc.
I think It is not sufficient.

(3) unsigned int does not have padding bits

should be preferible.

In presence of padding bits

(*(unsigned int *)a2) can have many representations .

In this case with assignment

*(unsigned int *)a1=*(unsigned int *)a2;

you are not guaranteed to copy all bytes correctly.

--
Giorgio Silvestri

Jul 25 '06 #12
On Mon, 24 Jul 2006 12:58:09 GMT, Frederick Gotham
<fg*******@SPAM .comwrote:
quantumred posted:
unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};

*(unsigned int *)a1=*(unsigned int *)a2;


This will work perfectly if:

(1) 4 == sizeof(int)

(2) alignof(char[4]) >= alignof(int)
To be pedantic, alignof (unsigned char [4]) % alignof (unsigned int)
== 0. Although it is clearly expected and normally true that stricter
alignments (if they exist at all) are multiples of all looser ones,
that isn't explicitly required; a perverse (DS9k) implementation could
align char[4] to 3 and int to 5.

To be accurate, alignof(a1) % alignof(int) == 0
and alignof(a2) % alignof(int) . An implementation reasonably could
(and I use one which does) align 'top-level' variables a1 and a2 more
strictly than u_char[4] requires, and in fact sufficient for u_int.
>
The C Standard does not provide these guarantees for all platforms and
implementations . What you have is non-portable, platform-specific code.

It seems to me that the author was aiming to optimise the copying of an
array. I'd probably take a route somewhat akin to the following:

#define DEFINE_SOLE_MEM BER(Type) \
\
struct SoleMember##Typ e { \
Type obj; \
} /* Usage code provides semi-colon */ \

#define SoleMember(Type ) SoleMember##Typ e
Presumably for C you meant either SoleMember(Type ) to expand to
struct SoleMember##Typ e

or the DEFINE_SOLE_MEM BER to do a typedef like
typedef struct { Type obj; } SoleMember##Typ e

<OTIn C++ your combination would work. </>
int main()
{
unsigned char a1[4]= {5,10,15,20};
unsigned char a2[4]= {25,30,35,40};

typedef char char4[4];

DEFINE_SOLE_MEM BER(char4);

*(SoleMember(ch ar4)*)a1 = *(SoleMember(ch ar4) const*)a2;
}
(The Standard guarantees that you can cast from a pointer to a struct, to a
pointer to the type of its first member. However, I don't believe it
guarantees the reverse -- so the code might be slightly dubious.)
It does guarantee conversion from _actual_ (and hence correctly
aligned) first member back to the struct. But here of course the issue
is that _a variable of that same type_ may be misaligned. This is only
likely to be needed and happen in practice if the struct contains
other stricter members, but is formally allowed even if it doesn't.

- David.Thompson1 at worldnet.att.ne t
Jul 31 '06 #13

Jack Klein wrote:
On Mon, 24 Jul 2006 12:58:09 GMT, Frederick Gotham
<fg*******@SPAM .comwrote in comp.lang.c:
quantumred posted:
unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};
>
*(unsigned int *)a1=*(unsigned int *)a2;

This will work perfectly if:

(1) 4 == sizeof(int)

(2) alignof(char[4]) >= alignof(int)
The C Standard does not provide these guarantees for all platforms and
implementations . What you have is non-portable, platform-specific code.

To be perfectly correct, the C standard does not provide these
guarantees for ANY platform OR implementation.
And even if it did, the behaviour would still be
undefined.

Jul 31 '06 #14
Dave Thompson <da************ *@worldnet.att. netwrites:
On Mon, 24 Jul 2006 12:58:09 GMT, Frederick Gotham
<fg*******@SPAM .comwrote:
>quantumred posted:
unsigned char a1[4]= { 5,10,15,20};
unsigned char a2[4]= { 25,30,35,40};

*(unsigned int *)a1=*(unsigned int *)a2;


This will work perfectly if:

(1) 4 == sizeof(int)

(2) alignof(char[4]) >= alignof(int)
To be pedantic, alignof (unsigned char [4]) % alignof (unsigned int)
== 0. Although it is clearly expected and normally true that stricter
alignments (if they exist at all) are multiples of all looser ones,
that isn't explicitly required; a perverse (DS9k) implementation could
align char[4] to 3 and int to 5.
[...]

Actually, I don't think it could. int could have an alignment of 5,
but char[4] can't have a required alignment of 3. Given:

char arr[2][4]

the two elements of arr must be adjacent and must each have a size of
4 bytes.

In general, because there can't be gaps between array elements, the
size of a type must be a multiple of its alignment. (The
implementation can adjust the size if necessary to make this happen,
for example by adding padding bits.)

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 31 '06 #15
On Mon, 31 Jul 2006 07:31:53 GMT, Keith Thompson <ks***@mib.or g>
wrote:
Dave Thompson <da************ *@worldnet.att. netwrites:
To be pedantic, alignof (unsigned char [4]) % alignof (unsigned int)
== 0. Although it is clearly expected and normally true that stricter
alignments (if they exist at all) are multiples of all looser ones,
that isn't explicitly required; a perverse (DS9k) implementation could
align char[4] to 3 and int to 5.
[...]

Actually, I don't think it could. int could have an alignment of 5,
but char[4] can't have a required alignment of 3. Given:

char arr[2][4]

the two elements of arr must be adjacent and must each have a size of
4 bytes.
Oops, you're right. I didn't think far enough.
In general, because there can't be gaps between array elements, the
size of a type must be a multiple of its alignment. (The
implementation can adjust the size if necessary to make this happen,
for example by adding padding bits.)
Except to character types, or at least unsigned char and thus possibly
plain char. And, by the reasoning above, arrays of them.

But I still maintain in the example upthread int could (perversely)
require an alignment not supplied by char[4].

- David.Thompson1 at worldnet.att.ne t
Aug 14 '06 #16

Dave Thompson wrote:
On Mon, 31 Jul 2006 07:31:53 GMT, Keith Thompson <ks***@mib.or g>
wrote:
Dave Thompson <da************ *@worldnet.att. netwrites:
To be pedantic, alignof (unsigned char [4]) % alignof (unsigned int)
== 0. Although it is clearly expected and normally true that stricter
alignments (if they exist at all) are multiples of all looser ones,
that isn't explicitly required; a perverse (DS9k) implementation could
align char[4] to 3 and int to 5.
[...]

Actually, I don't think it could. int could have an alignment of 5,
but char[4] can't have a required alignment of 3. Given:

char arr[2][4]

the two elements of arr must be adjacent and must each have a size of
4 bytes.
Oops, you're right. I didn't think far enough.
In general, because there can't be gaps between array elements, the
size of a type must be a multiple of its alignment. (The
implementation can adjust the size if necessary to make this happen,
for example by adding padding bits.)

Except to character types, or at least unsigned char and thus possibly
plain char. And, by the reasoning above, arrays of them.

But I still maintain in the example upthread int could (perversely)
require an alignment not supplied by char[4].
Are you saying anything more than, eg, char[4] can
require four byte alignment whereas int could allow
alignment of either 0 or 2 mod 4? Certainly the
set of alignments allowed for int must have some
overlap with the set of alignments allowed for
char[4].

Aug 14 '06 #17
en******@yahoo. com writes:
Dave Thompson wrote:
>On Mon, 31 Jul 2006 07:31:53 GMT, Keith Thompson <ks***@mib.or g>
wrote:
Dave Thompson <da************ *@worldnet.att. netwrites:
To be pedantic, alignof (unsigned char [4]) % alignof (unsigned int)
== 0. Although it is clearly expected and normally true that stricter
alignments (if they exist at all) are multiples of all looser ones,
that isn't explicitly required; a perverse (DS9k) implementation could
align char[4] to 3 and int to 5.
[...]

Actually, I don't think it could. int could have an alignment of 5,
but char[4] can't have a required alignment of 3. Given:

char arr[2][4]

the two elements of arr must be adjacent and must each have a size of
4 bytes.
Oops, you're right. I didn't think far enough.
In general, because there can't be gaps between array elements, the
size of a type must be a multiple of its alignment. (The
implementation can adjust the size if necessary to make this happen,
for example by adding padding bits.)

Except to character types, or at least unsigned char and thus possibly
plain char. And, by the reasoning above, arrays of them.

But I still maintain in the example upthread int could (perversely)
require an alignment not supplied by char[4].

Are you saying anything more than, eg, char[4] can
require four byte alignment whereas int could allow
alignment of either 0 or 2 mod 4? Certainly the
set of alignments allowed for int must have some
overlap with the set of alignments allowed for
char[4].
int could have an alignment of, say, 5. If char[4] required an
alignment of 4, then a union of an int and a char[4] would require an
alignment of at least 20.

But I'm not sure that char[4] can require an alignment stricter than 1
byte. For example, this:

char buf[5];
char (*p)[4] = (char(*)[4])(buf+1);

make p a pointer to a char[4] array that aliases elements 1..4 of buf.
Is this guaranteed to make p a valid pointer?

More generally, may an array of type X have a stricter alignment
requirement than type X itself?

An implementation may, of course, choose to align a char array, or
even a single char object, on, say, a word boundary; the question is
whether it can require such strict alignment.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 14 '06 #18
In article <ln************ @nuthaus.mib.or g>,
Keith Thompson <ks***@mib.orgw rote:
>More generally, may an array of type X have a stricter alignment
requirement than type X itself?
No: that would interfere with the requirement that the address of
a variable of non-aggregate type is equivilent to the address
of an array of length 1 of that type. (If I recall correctly, this
requirement is part of the definition of pointer comparison.)
--
Programming is what happens while you're busy making other plans.
Aug 14 '06 #19

Walter Roberson wrote:
In article <ln************ @nuthaus.mib.or g>,
Keith Thompson <ks***@mib.orgw rote:
More generally, may an array of type X have a stricter alignment
requirement than type X itself?

No: that would interfere with the requirement that the address of
a variable of non-aggregate type is equivilent to the address
of an array of length 1 of that type. (If I recall correctly, this
requirement is part of the definition of pointer comparison.)
Keith was talking about arrays of length greater than one.

Aug 15 '06 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
19275
by: David Rager | last post by:
Howdy, Put briefly, I have an array of chars, which I would like to access in pairs of bytes via casting the array to an array of shorts. I'm trying to be as elegant as possible. Below is a program with a failed attempt. Hopefully it will help clarify the issue :). Thanks!
20
2109
by: j0mbolar | last post by:
I was reading page 720 of unix network programming, volume one, second edition. In this udp_write function he does the following: void udp_write(char *buf, <everything else omitted) struct udpiphdr *ui; struct ip *ip; ip = (struct ip *) buf;
7
3676
by: yufufi | last post by:
lets say we have a 'shape' class which doesn't implement IComparable interface.. compiler doesn't give you error for the lines below.. shape b= new shape(); IComparable h; h=(IComparable)b; but it complains for the following lines
3
54258
by: glenn | last post by:
I have a COM server that is returning a type Object that I need to cast as a byte array. Can anyone tell me how this is performed in C#? Thanks, glenn
3
2132
by: Dennis | last post by:
If I have a byte how would I port code from C++ to manipulate the byte array as if it were a long? For example: // C++ // assume the following // unsigned char* m_pPalette; // unsigned char* m_pData; //
4
4504
by: kelli | last post by:
i am new to c# so if this is a trivial problem, forgive me! i've searched the web and after 2 days still cannot solve it. i am converting a c++ application to c# - the problem code is listed below. the c++ code uses a byte array (msg) to hold a serial message. since the message can be of different layouts, the array is cast to the appropriate layout "type" (struct SERIAL_CAN_MSG_TYPE, in this example). to complicate things, there is an...
12
3325
by: O.B. | last post by:
I'm trying to do a static_cast at runtime in C# and as I understand it, "as" is the keyword to use. Unfortunately, the compiler is trying to do the cast a compilation time. See below. /* TestA.cs */ namespace TEST { class TestA { public ushort val1; public ushort val2; public ushort val3;
57
3238
by: buuuuuum | last post by:
why array can't be assigned, like structs?
11
7287
by: jois.de.vivre | last post by:
I am interfacing with a third party API (written in C, if that matters) that has an "event handler" function with the following definition: void event_handler(int event_code, unsigned long user_data); The function takes an event code along with the user data but does not act on or change the user data. In my application, I want to pass a pointer as the user data. This pointer is to an array allocated with new, say, as follows:
0
9180
Oralloy
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8920
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8887
tracyyun
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6536
isladogs
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5877
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4633
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3060
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2351
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2012
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.