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

Discussion in 'C Programming' started by Myth__Buster, Feb 1, 2013.

  1. Myth__Buster

    Myth__Buster Guest

    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>
     
    Myth__Buster, Feb 1, 2013
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris
    Replies:
    34
    Views:
    1,550
  2. weston
    Replies:
    1
    Views:
    264
    Richard Cornford
    Sep 22, 2006
  3. Myth__Buster
    Replies:
    13
    Views:
    384
    Anand Hariharan
    Feb 26, 2013
  4. Myth__Buster
    Replies:
    0
    Views:
    256
    Myth__Buster
    Feb 1, 2013
  5. Myth__Buster
    Replies:
    1
    Views:
    222
    Myth__Buster
    Feb 1, 2013
Loading...

Share This Page