1

I am having a code that says:

#include<stdio.h>

typedef struct string{
    char *ch_ptr;
}str_t;

#define newdef(a,b) \
    char a ## sumthing[b * sizeof(str_t)]; \
    str_t *a = (str_t *)a ## sumthing

main(){
    newdef(input,5);
    /*     some lines of code */
}

Optional changes to code:

#include<stdio.h>

typedef struct string{
    char *ch_ptr;
}str_t;

#define newdef(a,b) \
    char a ## sumthing[b * sizeof(str_t)]; \
    str_t *var1 = (str_t *)a ## sumthing

main(){
    newdef(input,5)="Hello";
    printf("%s\n",input);
    /*     some lines of code */
}

Can anyone explain what this code segment means? Is input in this code a string (hope not) or a variable? If a variable then why doesn't the compiler throw an undeclared variable error?

Anirban
  • 550
  • 3
  • 19
  • 1
    `#define` creates a preprocessor macro (look that up if you don't know what it is). In this case the macro is called `newdef` and it takes two parameters; `a` and `b`. `newdef(input,5)` gets expanded into the macro definition (`char a ## […]`) with every occurrence of `a` expanded into `input` and every `b` expanded into `5`. `##` is a concatenation operator, so `a ## sumthing` turns into `inputsumthing` (in this case). – Biffen Mar 30 '16 at 09:21
  • ## Is just the preprocessor concatenation operator, if it's your question :) – Raph Schim Mar 30 '16 at 09:23

2 Answers2

5

Its a preprocessor concatenation operator, and can only be used when defining preprocessor macros.

Lets take a simple example

#define CONCAT(a, b) a ## b

int CONCAT(foo, bar);

In the above code, the invocation of CONCAT(foo, bar) will be replaced by

int foobar;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
3

input is neither a string nor a variable, it's a preprocessing token.

## is the "token-pasting" operator.

The first macro expands newdef(input,5); into

char inputsumthing[5 * sizeof(str_t)]; str_t *input = (str_t *) intputsumthing;

That is, it expands into a declaration of a variable named like the first parameter.

Your "optional changes" would unconditionally name the declared pointer variable "var1" and make it impossible to use the macro more than once in the same scope.
Also, newdef(input,5)="Hello"; would expand to an error:

char inputsumthing[5 * sizeof(str_t)]; 
str_t *var1 = (str_t *)inputsumthing = "Hello";

As a side note, the original macro seems to mostly be an obfuscation of

str_t inputs[5];
str_t* input = inputs;
molbdnilo
  • 64,751
  • 3
  • 43
  • 82