473,569 Members | 3,035 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 #1
20 3481
quantumred wrote:
>
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?
There's the possibility that a1 and a2 don't
have the proper alignment for type unsigned.

--
pete
Jul 24 '06 #2

probably a little quicker then memcpy, no function call overhead.

prob. safe if you know how your compiler treats these types, or you can
set appropriate command line params to your compiler (or use some
pragmas)
to force alignment and so on.

Not really worth the trouble i suspect though: not at all clear what is
happening, and
what you gonna save? a few instructions on a P4/Athlon/etc is nothin!

Jul 24 '06 #3
Aaron Gage wrote:

Please quote what you are replying to, Google now makes this easy. See
the last link in my sig for more information.

The code in question was:
quantumred wrote:

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?
probably a little quicker then memcpy, no function call overhead.
On most modern compiler there is probably no difference in speed.
prob. safe if you know how your compiler treats these types, or you can
set appropriate command line params to your compiler (or use some
pragmas)
to force alignment and so on.
Definitely *not* safe. It might work on the OPs specific platform, but
it is not safe because the code might then get reused on a system where
it does not work.
Not really worth the trouble i suspect though: not at all clear what is
happening, and
what you gonna save? a few instructions on a P4/Athlon/etc is nothin!
Definitely not worth the trouble.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jul 24 '06 #4
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.

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

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.)

--

Frederick Gotham
Jul 24 '06 #5
Frederick Gotham wrote:
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.

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

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.)
In particular, it doesn't solve the alignment issue. The
alignment requirement for a struct object need not be a simple
function of the alignment requirements of its elements; the fact
that the enclosing object is a struct may impose alignment
requirements of its own. Therefore, either or both of the casts
in the above code may produce invalid struct pointers.

It also doesn't solve the size issue. The sizeof a struct
is at least as great as the sum of the sizeof its elements, but
may be greater. In the code above, sizeof(SoleMemb erchar4) may
be greater than sizeof(char4), and if so the assignment tries to
read from memory beyond the end of the a2[] array, and undefined
behavior ensues.

One is left to ask: What issue *does* the above code solve?
Is it in any way better than the broken original, or is it just
a more sophisticated expression of the same errors?

--
Eric Sosman
es*****@acm-dot-org.invalid
Jul 24 '06 #6
Eric Sosman posted:
One is left to ask: What issue *does* the above code solve?
Is it in any way better than the broken original, or is it just
a more sophisticated expression of the same errors?

The code makes the (naive?) assumption that a struct consisting of a sole
member is identical to the member on its own.

Is this guaranteed? No.

Is it reasonable? I don't know, but it sounds sort of logical.
<OFF-TOPIC>
You've just given me an idea for a post to comp.std.c++.
</OFF-TOPIC>

--

Frederick Gotham
Jul 24 '06 #7
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.
--
"The way I see it, an intelligent person who disagrees with me is
probably the most important person I'll interact with on any given
day."
--Billy Chambless
Jul 24 '06 #8
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)
The C Standard does not provide these guarantees for all platforms and
implementations .
[...]

Nor does it provide a function or operator called "alignof".

(That's not a complaint, just a clarification; your hypothetical
"alignof" operator is a good way to express the idea.)

--
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 24 '06 #9
"quantumred " <qu********@gma il.comwrote:
# 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?

If you have a 32 bit data path between memory and cpu, it's 4 times
faster to move an aligned word at a time instead of a byte at a time.
This can be a win on programs that do a lot of data movement on
aligned pointers.

A good implementation of memcpy will check lengths and alignments and
do the fastest possible move available on that particular machine.
Typical implementations are something else. Even a good implementation
without compiler assistance requires start up code everytime it is
called to determine what is the fastest move; often the compiler will
have all that information available, but it doesn't often happen that
information is made available to memcpy.

This kind of code is either defense against mediocre memcpy
implementations or a vain belief the programmer is cleverer
than the compiler.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
But I do believe in this.
Jul 24 '06 #10

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

Similar topics

4
19201
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
2060
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
3654
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
54232
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
2119
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
4499
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...
12
3308
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
3201
by: buuuuuum | last post by:
why array can't be assigned, like structs?
11
7270
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...
0
7703
marktang
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7926
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. ...
1
7679
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...
0
7983
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...
0
6287
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5223
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...
0
3657
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3647
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1228
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.