-2

I need a macro in C that does this:

ARRINIT(10, 0) => {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

As per my understanding however, there is no conventional loop in C macros. So I tried to write a function that takes a number and a void pointer and returns an initialized array. But that required pointers and I want it to be used with constant numbers. Also, I want to use this with everything: functions, int's, floats, strings etc. So I most likely need a macro. How may I achieve this effect?

kahveciderin
  • 312
  • 1
  • 3
  • 22
  • 1
    Have you looked at `memset`? – another.anon.coward Aug 05 '21 at 19:25
  • It is possible. The naming is not great (it is not necessarily array init, could be struct init as well). This is also quite hard and non-trivial. You can look at https://github.com/rofl0r/chaos-pp for inspiration. – SergeyA Aug 05 '21 at 19:29
  • @another.anon.coward `memset` would be quite different. – SergeyA Aug 05 '21 at 19:29
  • @Jim Rhodes I want to loop in the preprocessor – kahveciderin Aug 05 '21 at 21:04
  • 1
    `cpp` _won't_ do this for you [even under duress/torture :-)]. You want a "code generator" program. Either a "real" macro processor like `m4` or a `perl/python/c` program that you write and add to your Makefile to generate the source code you want (i.e. _Metaprogramming_). – Craig Estey Aug 06 '21 at 01:37
  • Or, consider foregoing the elaborate compile time statically initialized arrays and just write an initialization function in your C code. For complex stuff like you want, the startup time saved with the initializer probably isn't worth the complexity. And, it would only work for fixed size arrays (size is known at compile time). So, if you need to initialize a dynamic array (e.g. `VLA` or pointer from `malloc`), you'll need the runtime initialization function. I'm a big fan [and user] of macros, but I balance the cleverness against the complexity/obscurity of doing so. – Craig Estey Aug 06 '21 at 01:41
  • 1
    @CraigEstey "`cpp` _won't_ do this for you [even under duress/torture :-)]" By "this", do you mean [this](http://coliru.stacked-crooked.com/a/8c6d56530888d051)? – H Walters Aug 06 '21 at 05:43
  • 1
    @HWalters Oh, what a hack! ;-) Does it work for C, too? -- Anyway, to make this more useful, I'd prefer if `REPEAT(4, x)` expands to `x, x, x, x` without the braces and the final comma. This way one can use multiples of it to fill regions in the same array/struct/anything. However, I'll never use such a macro, simply because it hides too much. – the busybee Aug 06 '21 at 07:18

1 Answers1

1

Here is a wacky workaround that I thought of. In order to fulfill this wish though:

I want to use this with everything: functions, int's, floats, strings etc.

I could not escape using pointers

So first, prepare a header file (called "macroArray.h" in this example) like this:

#ifndef MACRO_ARRAY_H
#define MACRO_ARRAY_H

#include <stdio.h>
#include <stdlib.h>

#define ARRINIT(SIZE, INIT_VAL) initArr(SIZE, INIT_VAL)

typedef int Item;

Item **initArr(int aSize, Item *initVal)
{
    Item **arr = malloc(aSize * sizeof *arr);

    if (arr != NULL)
    {
        for (int i = 0; i < aSize; i++) 
        {
            *(arr + i) = initVal;
        }
    }
    else
    {
        fprintf(stderr, "Failed to allocate memory!\n");
        exit(1);
    }

    return arr;
}

#endif /* MACRO_ARRAY_H */

Here is a usage example:

#include "macroArray.h"

int main(void) 
{   
    int size = 10;
    int num = 0;
    
    int **arr = ARRINIT(size, &num);

    for (int i = 0; i < size; i++)
    {
        printf("%d ", **(arr + i));
    }

    printf("\n");

    free(arr);

    return 0;
}

So...

ARRINIT(10, 0) => {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

Can be done!

What do you think?

Some drawbacks:

  • In order to change the type of array, you must change the alias defined by typedef in the header file; this is not very "user friendly"
  • You must not forget to free() the dynamically allocated array
  • This probably does not fulfill your wish to use "constant numbers"
  • This is like something "that works, but not really"; could be improved
Jiho Kim
  • 158
  • 8