C宏问题:函数/结构体的重新定义

发布于 2024-09-05 08:39:31 字数 1891 浏览 3 评论 0原文

给出以下代码(它是一个宏,根据所包含的类型生成列表数据结构的代码)。

list.h

#ifndef _LIST_H
#define _LIST_H

#ifdef __cplusplus
extern "C" {
#endif

#define LIST_TEMPLATE_INIT(type) \
    typedef struct __list_s_##type { \
        struct __list_s_##type *next; \
        type value; \
    } __list_##type; \
\
    __list_##type * __list_##type##_malloc(type value){ \
        __list_##type * list = NULL; \
        list = malloc(sizeof(*list)); \
        list->value = value; \
        return list; \
    }\
\
    void __list_##type##_free(__list_##type *list){\
        __list_##type * back = list;\
        while(list=list->next){\
            free(back);\
            back = list;\
        }\
    }
#define LIST_TYPE(type) __list_##type
#define LIST_MALLOC(type,value) __list_##type##_malloc(value)
#define LIST_FREE(type,list) __list_##type##_free(list)
#define LIST_DATA(list) (list->value)

#ifdef __cplusplus
}
#endif

#endif /* _LIST_H */

下面是上面代码的工作原理:

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

/*
 * 
 */
LIST_TEMPLATE_INIT(int)
int main(int argc, char** argv)
{
 LIST_TYPE(int)* list = NULL;
 list = LIST_MALLOC(int, 5);
 printf("%d",LIST_DATA(list));
 LIST_FREE(int,list);
 return (0);
}

我的问题是,是否有可能以某种方式调用:LIST_TEMPLATE_INIT(int),只要我想要多少次,以分散的方式?

目前的问题是,在另一个文件中调用 LIST_TEMPLATE_INIT(int) 会引发编译错误(由于函数重新定义):

错误示例:

error: redefinition of ‘struct __list_s_int’
 error: redefinition of ‘struct __list_s_int’
error: conflicting types for ‘__list_int’
note: previous declaration of ‘__list_int’ was here
error: conflicting types for ‘__list_int_malloc’
note: previous definition of ‘__list_int_malloc’ was here
error: conflicting types for ‘__list_int_free’
note: previous definition of ‘__list_int_free’ was here

Given the following code (it's a macro that generates code for a list data structure, based on the contained type).

list.h

#ifndef _LIST_H
#define _LIST_H

#ifdef __cplusplus
extern "C" {
#endif

#define LIST_TEMPLATE_INIT(type) \
    typedef struct __list_s_##type { \
        struct __list_s_##type *next; \
        type value; \
    } __list_##type; \
\
    __list_##type * __list_##type##_malloc(type value){ \
        __list_##type * list = NULL; \
        list = malloc(sizeof(*list)); \
        list->value = value; \
        return list; \
    }\
\
    void __list_##type##_free(__list_##type *list){\
        __list_##type * back = list;\
        while(list=list->next){\
            free(back);\
            back = list;\
        }\
    }
#define LIST_TYPE(type) __list_##type
#define LIST_MALLOC(type,value) __list_##type##_malloc(value)
#define LIST_FREE(type,list) __list_##type##_free(list)
#define LIST_DATA(list) (list->value)

#ifdef __cplusplus
}
#endif

#endif /* _LIST_H */

And here is how the above code works:

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

/*
 * 
 */
LIST_TEMPLATE_INIT(int)
int main(int argc, char** argv)
{
 LIST_TYPE(int)* list = NULL;
 list = LIST_MALLOC(int, 5);
 printf("%d",LIST_DATA(list));
 LIST_FREE(int,list);
 return (0);
}

My question, is it possible to somehow be able to call : LIST_TEMPLATE_INIT(int), as many times as I want, in a decentralized fashion ?

The current issue with this right now is that calling LIST_TEMPLATE_INIT(int) in another file raise compilation errors (because of function redefinition):

Example of error:

error: redefinition of ‘struct __list_s_int’
 error: redefinition of ‘struct __list_s_int’
error: conflicting types for ‘__list_int’
note: previous declaration of ‘__list_int’ was here
error: conflicting types for ‘__list_int_malloc’
note: previous definition of ‘__list_int_malloc’ was here
error: conflicting types for ‘__list_int_free’
note: previous definition of ‘__list_int_free’ was here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合久必婚 2024-09-12 08:39:31

我建议创建不同的宏来声明和定义列表结构,然后为每个宏使用单独的头文件和源文件:

list.h

#ifndef _LIST_H    
#define _LIST_H    

#define LIST_TEMPLATE_DECLARE(type)                   \
    struct __list_##type;                             \
    typedef struct __list_##type __list_##type;       \
    struct __list_##type {                            \
        struct __list_##type * next;                  \
        type value;                                   \
    };                                                \
                                                      \
__list_##type * __list_##type##_malloc(type value);   \
void __list_##type##_free(__list_##type * list);

#define LIST_TEMPLATE_DEFINE(type)                    \
__list_##type * __list_##type##_malloc(type value) {  \
    __list_##type * list = NULL;                      \
    list = malloc(sizeof(*list));                     \
    list->value = value;                              \
    return list;                                      \
}                                                     \
void __list_##type##_free(__list_##type * list) {     \
    __list_##type * back = list;                      \
    while(list=list->next){                           \
        free(back);                                   \
        back = list;                                  \
    }                                                 \
}

#define LIST_TYPE(type) __list_##type    
#define LIST_MALLOC(type,value) __list_##type##_malloc(value)    
#define LIST_FREE(type,list) __list_##type##_free(list)    
#define LIST_DATA(list) (list->value)    

#endif /* _LIST_H */    

int_list.h

#ifndef INT_LIST_H_
#define INT_LIST_H_

#include "list.h"
LIST_TEMPLATE_DECLARE(int)

#endif /* INT_LIST_H_ */

int_list.c

#include "int_list.h"

LIST_TEMPLATE_DEFINE(int)

其他.c

#include "int_list.h"

int some_function(int argc, char** argv)
{
    LIST_TYPE(int)* list = NULL;
    list = LIST_MALLOC(int, 5);
    printf("%d",LIST_DATA(list));
    LIST_FREE(int,list);
    return (0);
}

I would suggest creating different macros to declare and define the list structure, then using separate header and source files for each:

list.h:

#ifndef _LIST_H    
#define _LIST_H    

#define LIST_TEMPLATE_DECLARE(type)                   \
    struct __list_##type;                             \
    typedef struct __list_##type __list_##type;       \
    struct __list_##type {                            \
        struct __list_##type * next;                  \
        type value;                                   \
    };                                                \
                                                      \
__list_##type * __list_##type##_malloc(type value);   \
void __list_##type##_free(__list_##type * list);

#define LIST_TEMPLATE_DEFINE(type)                    \
__list_##type * __list_##type##_malloc(type value) {  \
    __list_##type * list = NULL;                      \
    list = malloc(sizeof(*list));                     \
    list->value = value;                              \
    return list;                                      \
}                                                     \
void __list_##type##_free(__list_##type * list) {     \
    __list_##type * back = list;                      \
    while(list=list->next){                           \
        free(back);                                   \
        back = list;                                  \
    }                                                 \
}

#define LIST_TYPE(type) __list_##type    
#define LIST_MALLOC(type,value) __list_##type##_malloc(value)    
#define LIST_FREE(type,list) __list_##type##_free(list)    
#define LIST_DATA(list) (list->value)    

#endif /* _LIST_H */    

int_list.h:

#ifndef INT_LIST_H_
#define INT_LIST_H_

#include "list.h"
LIST_TEMPLATE_DECLARE(int)

#endif /* INT_LIST_H_ */

int_list.c:

#include "int_list.h"

LIST_TEMPLATE_DEFINE(int)

other.c:

#include "int_list.h"

int some_function(int argc, char** argv)
{
    LIST_TYPE(int)* list = NULL;
    list = LIST_MALLOC(int, 5);
    printf("%d",LIST_DATA(list));
    LIST_FREE(int,list);
    return (0);
}
横笛休吹塞上声 2024-09-12 08:39:31

使底层结构类型匿名。这将允许您定义任意数量的内容:

#define LIST_TEMPLATE_INIT(type) \
    typedef struct { \
        struct __list_s_##type *next; \
        type value; \
    } __list_##type; \

Make the underlying struct type anonymous. This will allow you to define as many as your heart desires:

#define LIST_TEMPLATE_INIT(type) \
    typedef struct { \
        struct __list_s_##type *next; \
        type value; \
    } __list_##type; \
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文