I am working on a question from my computer programming course this semester and am unable to resolve a linker error that I am facing. Can someone take a look at the following files and let me know what's wrong. As instructed, I placed guards to ensure multiple definitions don't take place but the guards don't seem to be functioning as I expected because gcc is giving me and error saying that count and booksCatalog are defined multiple times.
Below are the C files and header files used for the question.
book.h
#ifndef BOOK_H
#define BOOK_H
#include <stdio.h>
typedef enum shelf{Shelf1=1,Shelf2=2,Shelf3=3,Shelf4=4} SHELF;
typedef struct book{
int ID;
SHELF shelfNum;
float price;
} BOOK;
// the function should create a new variable of the type struct book (typdefed as BOOK)
// using the parameters passed to it and return it.
BOOK newBook(int ID, SHELF shelfNum, float price);
// this function should print the values of the members of book1 (passed as parameter)
void printBook(BOOK book1);
#endif
book.c
#include "book.h"
BOOK newBook(int ID, SHELF shelfNum, float price)
{
// implement this function as per specification in books_def.h
BOOK newbook = {ID, shelfNum, price};
return newbook;
}
void printBook(BOOK book1)
{
// implement this function as per specification in books_def.h
printf("Book ID : %d\n", book1.ID);
printf("Book shelf number : %d\n", book1.shelfNum);
printf("Price of Book: %f\n\n",book1.price);
return;
}
catalog.h
#ifndef CATALOG_H
#define CATALOG_H
#include "book.h"
#define MAX_SIZE 100
BOOK booksCatalog[MAX_SIZE];
int count;
// This function should take an input parameter of the type struct book (typdefed as BOOK)
// and it to the booksCatalog array at position count. Then, count should be incremented.
void addBookToCatalog(BOOK book1);
// This function should print all the books that are added to booksCatalog array.
// It should use the printBook() function defined in "book_def.h" to print the details of each book.
void printBookCatalog();
// This function should sort the booksCatalog array based on the ID of the book.
void sortBookCatalogOnID();
#endif
catalog.c
#include "catalog.h"
void addBookToCatalog(BOOK book1)
{
// implement this function as per specification in books_catalog.h
if (count<MAX_SIZE)
{
booksCatalog[count]=book1;
count++;
}
else
printf("Catalog is full!");
return;
}
void printBookCatalog()
{
// implement this function as per specification in books_catalog.h
for (int i=0; i<count; i++)
{
printBook(booksCatalog[i]);
}
return;
}
void sortBookCatalogOnID()
{
// implement this function as per specification in books_catalog.h
int min;
for (int i=0; i<count-1; i++)
{
min=i;
for (int j=i+1; j<count; j++)
{
if ((booksCatalog[j].ID)<(booksCatalog[min].ID))
min=j;
}
BOOK temp = booksCatalog[i];
booksCatalog[i]=booksCatalog[min];
booksCatalog[min]=temp;
}
return;
}
main.c
#include "catalog.h"
#include "book.h"
int main()
{
count = 0;
BOOK book1 = newBook(1847, Shelf3, 8768.95);
BOOK book2 = newBook(5984, Shelf1, 7845.25);
BOOK book3 = newBook(6325, Shelf2, 3154.47);
BOOK book4 = newBook(5843, Shelf2, 1487.51);
BOOK book5 = newBook(7894, Shelf2, 541.29);
// printBook(book1);
// adding book1 to catalog of books
addBookToCatalog(book1);
addBookToCatalog(book2);
addBookToCatalog(book3);
addBookToCatalog(book4);
addBookToCatalog(book5);
printBookCatalog();
sortBookCatalogOnID();
printBookCatalog();
return 0;
}
In your header file catalog.h
you have the line
int count;
which is a tentative definition. In this case, this tentative definition will always become an actual definition.
This means the two source files main.c
and catalog.c
are each providing a definition of the variable count
. This violates the one-definition rule, even if the two definitions are identical.
In order to comply with the one-definition rule, only one of the source files should provide a definition. Therefore, I suggest that in the header file catalog.h
, you change the line
int count;
to:
extern int count;
That way, this line will be a declaration instead of a tentative definition.
However, now the variable count
is declared in main.c
and catalog.c
, but not defined anywhere. Therefore, in order to comply with the one-definition rule, you must also define the variables in one of the source files. This definition can be a (tentative) definition
int count;
or an explicit definition:
int count = 0;
The variable booksCatalog
has the same problem.