![]() |
Assigning an array to another array using C's assignment operator
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 not 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> |
| All times are GMT. The time now is 02:56 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.