Assigning an array to another array using C's assignment operator

M

Myth__Buster

Hi,

Here is one technique I have thought of to allow the assignment of
one
array to another in an indirect manner as it's not allowed directly
in
C. Before all, I would like to clarify that it's not something
designed to replace memcpy(). It's a technique to illustrate that how
good C's rich set of operators are. So, have a look and tell me what
you think of it. The code has all the reasoning for the different
operators I have used. Hope they make things straightforward.

Cheers,
Raghavan

<code>
#include <stdio.h>

// Applicable for arrays which are allocated dynamically also!
//
// The struct assignment below might result in the same code
// as it would if you happened to use memcpy() and the like.
// But, the purpose here is different!
//
// Purpose here is - To show that "C" indirectly allows array
// to array assignment. :)
//
// NOTE: The struct built for this suffers from no padding
// issues whatsoever since it involves just an array which
// must be contiguous and hence the compiler is forced not
// to play with it even if it wants to for whatever reasons!
//
// This macro doesn't check for the size of the
// destination and hence the user of this macro should
// take care of it.
//
// Why the use of comma-expression seemingly dummy
// one? Well, it is needed to inform the compiler that
// we are not punning the types but sincerely dealing
// with the given addresses to just copy data of the
// given size.
//
// Why seemingly useless (void *) casting? Well, again
// to inform the compiler that we are punning types as
// said earlier and this cast is required for
// convincing strict-aliasing=1.
//
// And why (void) casting in that comma expression?
// Well, it is to inform the compiler that we
// understand and hence ignore the value of it manually,
// for having no effect.
//
// The previous attempt would fail to compile if the
// size-based macro is used more than once in the same
// scope. So, I have used __LINE__ macro to build the
// unique data type in this attempt.
//
// Well, the user of this technique can build the
// required data type with unique name by himself/herself
// very easily. But, to ease his/her job a little, I am
// constructing the required unique data type with the
// help of the macro. And the uniqueness is based on the
// line number at which this macro gets placed. So, there
// will be a redefinition of a specific struct type if
// you happen to use this macro more than once in the
// same line. However, this limitation shouldn't be the
// reason not to use this technique which you can as well
// use directly by building the struct type by yourself
// in your code wherever you want.
//

#define AssignArraysLine(dest, src, line) \
( \
*(struct t##line \
{ \
char arr[ sizeof(src) ]; \
} *) ((void)dest, (void *)dest)\
= \
*(struct t##line *) \
((void)src, (void *)src) \
)

#define AssignArraysOfSizeLine(dest, src, size, line) \
( \
*(struct t##line \
{ \
char arr[ size ]; \
} *) ((void)dest, (void *)dest)\
= \
*(struct t##line *) \
((void)src, (void *)src) \
)

#define DummyMacro1(b, a, line) AssignArraysLine(b, a, line)
#define DummyMacro2(b, a, size, line) \
AssignArraysOfSizeLine(b, a, size, line)

// Don't get misled by the term static here in the below
// macro. It's just to signify that it's meant for only
// arrays defined using C array subscript([]) operator,
// which includes variable length arrays.
//
// NOTE : Don't use the macro more than once in the
// same line of your source as __LINE__ will be same
// and hence you would get type-redefinition error.
//
// And macros are known for side-effects, so be wary
// of them or you can just hand-code the comprehensive
// typecasting the above macro does without any
// problem - you can just ignore __LINE__ macro as
// well if you code by hand since you will not
// deliberately redefine a struct more than once!
#define AssignStaticArrays(b, a) DummyMacro1(b, a, __LINE__)

// Universal macro - works for all types of arrays.
//
// NOTE : Don't use the macro more than once in the same
// line of your source as __LINE__ will be same and hence
// you would get type-redefinition error.
//
// And macros are known for side-effects, so be wary of
// them or you can just hand-code the comprehensive
// typecasting the above macro does without any problem -
// you can just ignore __LINE__ macro as well if you code
// by hand since you will not deliberately redefine a
// struct more than once!
#define AssignArraysOfSize(b, a, size) \
DummyMacro2(b, a, size, __LINE__)

int main(void)
{
int a[ 10 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int b[ sizeof(a) ];

int i = 0;
printf("Array a : ");
while ( i < 10 )
{
printf("%d ", a[ i ]);
i++;
}
printf("\n");

AssignStaticArrays(b, a); // Once more in the
// same line -
// AssignStaticArrays(b, a);
// - Nope!

i = 0;
printf("Array b : ");
while ( i < 10 )
{
printf("%d ", b[ i ]);
i++;
}
printf("\n");

int z[ sizeof(a) ];
AssignStaticArrays(z, a); // This works as it's on a
// different line from the
// previous usage above!

i = 0;
printf("Array z : ");
while ( i < 10 )
{
printf("%d ", z[ i ]);
i++;
}
printf("\n");

int c[ sizeof(a) ];
AssignArraysOfSize(c, a, sizeof(a)); // Same rules
// apply to this
// macro usage
// as well as
// above.
i = 0;
printf("Array c : ");

while ( i < 10 )
{
printf("%d ", b[ i ]);
i++;
}
printf("\n");

int d[ sizeof(c) ];
AssignArraysOfSize(d, c, sizeof(c)); // Works as it's
// on a different
// line.
i = 0;
printf("Array d : ");

while ( i < 10 )
{
printf("%d ", d[ i ]);
i++;
}
printf("\n");


return 0;
}
</code>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top