Home > Net >  What does "arr_##name" mean in C?
What does "arr_##name" mean in C?

Time:01-07

This question is quite specific to a block of code I am trying to understand on Code Signal:

// arr_##name alloc_arr_##name(int len) { // arr_##name a = {len, len > 0 ? malloc(sizeof(type) * len) : NULL}; // return a;

In fact, if there is a clear explanation of the "Definition for arrays" that would be immensely helpful. Working code below for adjacent elements product in C: Given an array of integers, find the pair of adjacent elements that has the largest product and return that product.

// Definition for arrays:
// typedef struct arr_##name {
//   int size;
//   type *arr;
// } arr_##name;
//
// arr_##name alloc_arr_##name(int len) {
//   arr_##name a = {len, len > 0 ? malloc(sizeof(type) * len) : NULL};
//   return a;
// }
//
//
int solution(arr_integer inputArray) {
    int max = inputArray.arr[0] * inputArray.arr[1];
    for(int i=1; i<inputArray.size-1; i  ) {
        int product = inputArray.arr[i] * inputArray.arr[i 1];
        if (max < product) max = product;
    }
    return max;
}

CodePudding user response:

typedef struct arr_##name {
  int size;
  type *arr;
} arr_##name;

is not valid C. This will not compile.


However, ## is meaningful in macros. It concatenates two tokens into one.

#define foo( name ) arr_##name

foo( bar )

is equivalent to

arr_bar

CodePudding user response:

The commented-out code fragments:

// typedef struct arr_##name {
//   int size;
//   type *arr;
// } arr_##name;
//
// arr_##name alloc_arr_##name(int len) {
//   arr_##name a = {len, len > 0 ? malloc(sizeof(type) * len) : NULL};
//   return a;
// }

must be part of the body of one or more macros, which might look like this:

#define ARRAY_TYPE(name, type) \
    typedef struct arr_##name { \
        int size; \
        type *arr; \
    } arr_##name; \
    \
    arr_##name alloc_arr_##name(int len) { \
        arr_##name a = {len, len > 0 ? malloc(sizeof(type) * len) : NULL}; \
        return a; \
    }

The ## operator is a preprocessor operator (it can only appear validly in the body of a macro) that concatenates two tokens into a bigger one.

The macro might be used like this (note no training semicolon):

ARRAY_TYPE(shoes, double)

which would expand (give or take spacing) to:

typedef struct arr_shoes {
    int size;
    double *arr;
} arr_shoes;

arr_shoes alloc_arr_shoes(int len) {
    arr_shoes a = {len, len > 0 ? malloc(sizeof(double) * len) : NULL}; 
    return a;
}

Most people need pairs of shoes, hence the type double.

The code below your comments should have previously invoked:

ARRAY_TYPE(integer, int)

This creates the type arr_integer used in the code and creates the alloc_arr_integer() function that should have been used to create the value passed to the function solution().

  • Related