使用##运算符

时间:2016-03-30 09:14:28

标签: c gcc c-preprocessor

我有一个代码说:

#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 */
}

代码的可选更改:

#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 */
}

任何人都可以解释这段代码的含义吗?此代码中的input是字符串(希望不是)还是变量?如果变量那么为什么编译器不会抛出未声明的变量错误?

2 个答案:

答案 0 :(得分:5)

它是一个预处理程序连接运算符,只能在定义预处理器宏时使用。

让我们举一个简单的例子

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

int CONCAT(foo, bar);

在上面的代码中,CONCAT(foo, bar)的调用将替换为

int foobar;

答案 1 :(得分:3)

input既不是字符串也不是变量,它是预处理令牌。

##是“令牌粘贴”操作符。

第一个宏将newdef(input,5);扩展为

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

也就是说,它扩展为一个名为第一个参数的变量的声明。

您的“可选更改”将无条件地命名声明的指针变量“var1”,并且无法在同一范围内多次使用该宏。
此外,newdef(input,5)="Hello";会扩展为错误:

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

作为旁注,原始宏似乎主要是

的混淆
str_t inputs[5];
str_t* input = inputs;