1

I am using a structure that I defined in main.h and now using it in stack.c. In my main.h I have defined struct details and struct library. When I access them in stack.c I get the following error. When I am running a single main.c file then it's having no issues, so, I assume the issue lies in the stack.c or stack.h file.

Undefined symbols for architecture x86_64:
  "_details", referenced from:
      _main in main.o
      _library_details in main.o
      _push in stack.o
     (maybe you meant: _library_details)
  "_library", referenced from:
      _main in main.o
      _library_details in main.o
      _push in stack.o
     (maybe you meant: _library_details)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation

Here are my code snippets:

main.c

// write code below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"

void library_details(void);
FILE *fp;
int choice, indexer = 1;
//details_struct details[maxsize];
//library_struct library[maxsize];

int main(void)
{
     // library = malloc(sizeof(library_struct) * 2);
    fp = fopen("input.txt","r");

    library_details();

    for (int i = 1; i < indexer; i++)
    {
        if(library[i].type == is_book)
        {
            printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
        }
        else if(library[i].type == is_article)
        {
            printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
        }
    }
    fclose(fp);
    //free(library);
    return 0;
}

main.h

#ifndef __MAIN_H_
#define __MAIN_H_

enum book_type {is_book, is_article};
typedef struct library_struct
{
    enum book_type type;
    void *item;
}library_struct;

typedef struct details_struct
{
    char title[50];
    int pages;
}details_struct;

// external variables
extern int choice, indexer;
extern details_struct details[100];
extern library_struct library[100];

// library details
void library_details(void);

#endif // __MAIN_H_

stack.c

// stack.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
#include "main.h"

//functions declarations
void push(void);

stack books_stack[100];
int top = 0;

int stack_main(void)
{

    return 0;
}

void push()
{
    if(top >= 99)
    {
        printf("Stack Overflow\n");
        exit(-1);
    }
    else
    {
        if(library[top].type == is_book)
        {
            strcpy(books_stack[top].s_title, details[top].title);
            books_stack[top].s_pages = details[top].pages;
        }
    }
}

stack.h

#ifndef __STACK_H_
#define __STACK_H_

typedef struct stack
{
    char s_title[50];
    int s_pages;
}stack;

// functions declaration
void push();

#endif // __STACK_H_

Is there any issue with struct declarations?

  • 1
    Maybe it is because `library_details` isn't implemented anywhere? – Yonlif Jun 30 '20 at 19:22
  • its a function and its implemented in main.c file. The code was getting longer that's why I didn't insert it in the snippet. – Owais Qayum Jun 30 '20 at 19:26
  • Maybe it's misspelled in your definition. – Fiddling Bits Jun 30 '20 at 19:30
  • 1
    You've declared `library` and `details` as arrays in your header — that's good. Which file is going to define them? At the moment, no file defines them, hence the link-time error. One of `main.c` and `stack.c` should define the arrays (and still include the header that declares the arrays to ensure consistency). See also [How do I use `extern` to share variables between source files?](https://stackoverflow.com/a/1433387/15168) – Jonathan Leffler Jun 30 '20 at 19:34
  • @JonathanLeffler ohhhh i see, I thought when I declare library and details in header files and I call main.h in .c file then it will automatically be called. Can you kindly post it as an answer as to its the right answer and it fixed my issue. Thanks – Owais Qayum Jun 30 '20 at 19:40
  • You've been given useful answers and have accepted one; I'll not add another answer. – Jonathan Leffler Jun 30 '20 at 20:00

3 Answers3

2

Haven't used C in a while so I can't straight answer your question, but I made your code compile. However the compiled program has a C runtime abort. (Potentially some exception or something...) Examine this and consider the diff... in h you never instantiate, you declare, in c you instantiate your declaration. I don't know why you were doing extern + trying to instantiate... The other answers noted a most of the areas I messed with.

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"

FILE *fp;
int choice, indexer = 1;
int maxsize = 50;
details_struct details[100];
library_struct library[100];

void library_details(void)
{
    return;
}

int main(void)
{
    // library = malloc(sizeof(library_struct) * 2);
    fp = fopen("input.txt","r");

    library_details();

    for (int i = 1; i < indexer; i++)
    {
        if(library[i].type == is_book)
        {
            printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
        }
        else if(library[i].type == is_article)
        {
            printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
        }
    }
    fclose(fp);
    //free(library);
    return 0;
}

main.h

#ifndef __MAIN_H_
#define __MAIN_H_

enum book_type {is_book, is_article};
typedef struct library_struct
{
    enum book_type type;
    void *item;
} library_struct;

typedef struct details_struct
{
    char title[50];
    int pages;
} details_struct;

// external variables
extern int choice, indexer;
details_struct details[];
library_struct library[];

// library details
void library_details(void);

#endif // __MAIN_H_

stack.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"

//functions declarations
void push(void);

stack books_stack[100];
int top = 0;

int stack_main(void)
{
    return 0;
}

void push() {
    if (top >= 99) {
        printf("Stack Overflow\n");
        exit(-1);
    } else {
        if (library[top].type == is_book) {
            strcpy(books_stack[top].s_title, details[top].title);
            books_stack[top].s_pages = details[top].pages;
        }
    }

stack.h

#ifndef __STACK_H_
#define __STACK_H_
#include "main.h"

typedef struct stack
{
    char s_title[50];
    int s_pages;
} stack;

// functions declaration
void push();

#endif // __STACK_H_
}
GRAYgoose124
  • 621
  • 5
  • 24
  • yes I did a mistake by not defining library and library_details and it fixed my issue – Owais Qayum Jun 30 '20 at 19:43
  • 1
    Note that the header should use `extern details_struct details[];` and `extern library_struct library[];`. rather than omitting the keyword `extern`. All variables declared in headers should be prefixed with `extern` — and you shouldn't define variables in headers in general (there can be exceptions, but they're few and far between). Whether you include the size in the dimension of the array is negotiable; if the size is available, using it documents the code better, but it isn't formally crucial. – Jonathan Leffler Jun 30 '20 at 20:11
  • 1
    I'd also argue that since neither `top` nor `books_stack` is accessed from outside the file `stack.c`, they should both be defined as `static`. If they are to be accessed from outside the file, then they should be declared in a header (with `extern`). All functions that are not declared in a header should be `static` too — with the sole exception of `main()`, of course. – Jonathan Leffler Jun 30 '20 at 20:13
0

library an library_details are not exist in your code

You declare the function in main.h, but is not in in main.c

And, with library[], you are using but is not declared

0

You seem to have commented out the variable declarations:

//details_struct details[maxsize];
//library_struct library[maxsize];

So, neither details nor library are defined, and this is what the compiler is complaining about.

LSerni
  • 55,617
  • 10
  • 65
  • 107