Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple definition of function in the same place

I am trying to simulate generics in C by having some preprocessor definitions for a matrix type. Here is an excerpt of that:

#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)

In another file, byte_matrix.h, I am trying to define a matrix of uint8_t values, as follows:

#include "matrix.h"

typedef uint8_t byte;

__matrix_typedef(byte);

__matrix_allocator(byte)
__matrix_deallocator(byte)

When I try to compile, I get the following errors:

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

I cannot understand why it would point to times to the same line and complain about that definition, since every header I wrote has include guards. Could you please explain this to me? Also if you know of a better approach to my problem, please let me know. Thanks.

Also I need to compile with -std=c99 if that matters in this case.

like image 475
Victor Avatar asked Nov 16 '18 10:11

Victor


People also ask

When there are multiple definitions for the same function?

Answer: The multiple definitions with the same function name is called Function Overloading. The only difference among those functions is their parameter list which helps the compiler to recognize which function is being executed.

How do I fix multiple definitions in main?

The main function is the entry point for the C++ program execution. The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.

What is meant by multiple definition of Main?

Multiple definition of main means you have written main function more than once in your program which is not correct according to C language specifications.

What is multiple definition error in C?

What is multiple definition error in C? If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.20-Jul-2013.


1 Answers

A quick fix would be to add static to your function definitions. This will create a static copy of these functions in each compilation unit which references the header. If you want the functions to be inlined every time, this is the way to go.

An alternative way to do it would be to keep function declarations in a .h file, and actual definitions in a single .c file. This approach will avoid duplication, and the compiler will not inline them (unless your linker supports link time optimization).

The reason is that you are including this header file in multiple compilation units. After the preprocessor does all the textual replacements, you end up with actual separate function definitions inside your .c files. And if you don't specify that you want them to be static, they are by default extern, which means that now the compiler doesn't know how to differentiate them if some other part of the code wants to call them.

This is what you basically do whenever you create a header file: you create a list of declarations which will be included in many compilation units, but there is always a single extern definition in a single .c file.

like image 92
Groo Avatar answered Sep 19 '22 23:09

Groo