c - 在同一个地方定义多个函数

标签 c c99 generic-programming

我试图通过为 matrix 类型定义一些预处理器来在 C 中模拟泛型。这是其中的摘录:

#define __matrix_struct(TYPE) \
  struct { \
    uint32_t sz; \
    TYPE **ptr; \
  }

#define __matrix_t(TYPE) matrix_ ## TYPE
#define __matrix_ptr_t(TYPE) __matrix_t(TYPE) *

#define __matrix_typedef(TYPE) typedef __matrix_struct(TYPE) __matrix_t(TYPE)

#define __matrix_allocator_name(TYPE) TYPE ## _matrix_alloc
#define __matrix_allocator(TYPE) \
  __matrix_ptr_t(TYPE) __matrix_allocator_name(TYPE) (uint32_t sz) { \
    uint32_t i; \
    __matrix_ptr_t(TYPE) m = (__matrix_ptr_t(TYPE)) malloc(sizeof(__matrix_t(TYPE))); \
    m->ptr = (TYPE **) malloc(sz * sizeof(TYPE *)); \
    for (i = 0; i < sz; ++i) { \
      m->ptr[i] = (TYPE *) calloc(sz, sizeof(TYPE)); \
    } \
    return m; \
  }

#define __matrix_deallocator_name(TYPE) TYPE ## _matrix_free
#define __matrix_deallocator(TYPE) \
  void __matrix_deallocator_name(TYPE) (__matrix_ptr_t(TYPE) m) { \
    uint32_t i; \
    for (i = 0; i < m->sz; i++) { \
      free(m->ptr[i]); \
    } \
    free(m->ptr); \
    free(m); \
  }

#define matrix_alloc_ptr(TYPE, SIZE) __matrix_allocator_name(TYPE) (SIZE)
#define matrix_dealloc_ptr(TYPE, PTR_NAME) __matrix_deallocator_name(TYPE) (PTR_NAME)

在另一个文件 byte_matrix.h 中,我试图定义一个 uint8_t 值的矩阵,如下所示:

#include "matrix.h"

typedef uint8_t byte;

__matrix_typedef(byte);

__matrix_allocator(byte)
__matrix_deallocator(byte)

当我尝试编译时,出现以下错误:

CMakeFiles/tictac.dir/game/board.c.o: In function `byte_matrix_alloc':
/home/victor/dev/pc/tictac/game/../matrix/byte_matrix.h:13: multiple definition of `byte_matrix_alloc'
CMakeFiles/tictac.dir/main.c.o:/home/victor/dev/pc/tictac/game/../matrix/byte_matrix.h:13: first defined here
CMakeFiles/tictac.dir/game/board.c.o: In function `byte_matrix_free':
/home/victor/dev/pc/tictac/game/../matrix/byte_matrix.h:14: multiple definition of `byte_matrix_free'
CMakeFiles/tictac.dir/main.c.o:/home/victor/dev/pc/tictac/game/../matrix/byte_matrix.h:14: first defined here

我不明白为什么它会指向同一行的时间并提示该定义,因为我写的每个标题都包含守卫。你能给我解释一下吗?另外,如果您知道解决我的问题的更好方法,请告诉我。谢谢。

如果在这种情况下很重要,我还需要使用 -std=c99 进行编译。

最佳答案

一个快速修复方法是将 static 添加到您的函数定义中。这将在引用 header 的每个编译单元中创建这些函数的静态副本。如果您希望每次都内联函数,这是可行的方法。

另一种方法是将函数声明保存在 .h 文件中,并将实际定义保存在单个 .c 文件中。这种方法将避免重复,并且编译器不会将它们内联(除非您的链接器支持链接时间优化)。

原因是您在多个编译单元中包含了这个头文件。在预处理器完成所有文本替换之后,您最终会在 .c 文件中得到实际的单独函数定义。如果你不指定你希望它们是 static,它们默认是 extern,这意味着现在编译器不知道如何区分它们,如果代码的其他部分想要调用它们。

这就是您在创建头文件时基本上要做的事情:您创建一个声明列表,这些声明将包含在许多编译单元中,但在单个 .c 文件中始终只有一个外部定义。

关于c - 在同一个地方定义多个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53335887/

相关文章:

rust - 是否有任何特征可以指定数字功能?

c - 默认文件描述符表无法正常工作

c - 在 C 的 printf 中使用 size_t 指定字符串的精度

c - 如何将 “Type” 作为参数传递给 c 中的函数?

c - unsigned char 总是提升为 int 吗?

c - 无锁缓冲区

scala - 使用 StringContext 的通用字符串插值器

c - 从文件读取但读取的第一行是错误的

c - C if 语句编程

c - C中的列表维护问题