Search code examples
cincludec-preprocessor

How do I write a proper include and modulize my app in C?


I am once again asking for your help :) Cannot find a mistake in #includes, checked several times, have compared with geekstogeeks example and similar question here. So I've got:

/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:27: multiple definition of `RankNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:27: first defined here
/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:28: multiple definition of `SuitNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:28: first defined here
/tmp/ccWUaJkV.o:(.bss+0x0): multiple definition of `__odr_asan.SuitNames'
/tmp/ccA7hhxl.o:(.bss+0x0): first defined here
/tmp/ccWUaJkV.o:(.bss+0x1): multiple definition of `__odr_asan.RankNames'
/tmp/ccA7hhxl.o:(.bss+0x1): first defined here
collect2: error: ld returned 1 exit status

After compiling with

gcc -rdynamic -std=c11 `pkg-config --cflags gtk+-3.0` cardmethods.c main.c -o main `pkg-config --libs gtk+-3.0` -lX11

objects.obj

#include <stdbool.h>
#ifndef OBJECTS_O_
#define OBJECTS_O_

typedef struct myCard{
    bool trump;
    ...
} card;
typedef struct {
     ...
} widgetsPtrs;

card *Deck;//pointer to the deck.
/************************************HERE****************************/
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};

#endif

cardmethods.h

#include <stdbool.h>
#include <gtk/gtk.h>
#include "objects.obj"

#ifndef CARDMETHODS_H_
#define CARDMETHODS_H_

void addCard(card *pile, card *cardAdded);
void printAll(card *pile);
...


#endif

cardmethods.c

#include "cardmethods.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

void addCard(card *pile, card *cardAdded){
    ...
}
void printAll(card *pile){
    ...
}
...

main.c

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "cardmethods.h"

 ...

int main (int    argc,
      char **argv)
{
  ...
  return 0;
}


Solution

  • You've defined the variables RankNames and SuitNames in your header file. Because of this, they are defined in both main.c and cardmethods.c. Then when these files are linked, the linker finds multiple definitions.

    Change the header file to have external declarations of these variables (and Deck):

    extern card *Deck;
    extern char *RankNames[];
    extern char *SuitNames[];
    

    And put the definitions in one source file, probably cardmethods.c:

    card *Deck;
    char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
    char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};