Multiple definition of, error "foo" indeclarated...

Programming, for all ages and all languages.
Post Reply
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Multiple definition of, error "foo" indeclarated...

Post by deleted8917 »

I'm restructuring my code, but when I compile I have a lot of errors, mostly from the linker;
Linker:

Code: Select all

kernel/serial.o: In function `outb':
/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:47: multiple definition of `init_serial'
kmain.o:/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:58: first defined here
kernel/serial.o: In function `inb':
/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:54: multiple definition of `serial_received'
kmain.o:/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:65: first defined here
kernel/serial.o: In function `inb':
/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:54: multiple definition of `read_serial'
kmain.o:/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:65: first defined here
kernel/serial.o: In function `inb':
/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:54: multiple definition of `is_transmit_empty'
kmain.o:/mnt/c/Users/user/Desktop/osproject/kernel/kernel.h:65: first defined here
kernel/serial.o: In function `write_serial':
/mnt/c/Users/user/Desktop/osproject/kernel/serial.c:37: multiple definition of `write_serial'
kmain.o:/mnt/c/Users/user/Desktop/osproject/kernel/serial.h:40: first defined here
collect2: error: ld returned 1 exit status
compiler:

Code: Select all

In file included from kmain.c:5:0:
kernel/isrs.h: In function ‘fault_handler’:
kernel/isrs.h:142:22: error: ‘LIGHTGRAY’ undeclared (first use in this function)
         settextcolor(LIGHTGRAY, RED);
                      ^
kernel/isrs.h:142:22: note: each undeclared identifier is reported only once for each function it appears in
kernel/isrs.h:142:33: error: ‘RED’ undeclared (first use in this function)
         settextcolor(LIGHTGRAY, RED);
                                 ^
kmain.c: In function ‘kernelmain’:
kmain.c:24:38: error: expected ‘)’ before ‘nl’
     println("asd ����� �"nl);
                                      ^
kmain.c:33:13: error: ‘nl’ undeclared (first use in this function)
     println(nl);
             ^
But nl, LIGHTGRAY and RED macros exists!
Here's the code: https://gitlab.com/hextakatt/experimentalos
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Multiple definition of, error "foo" indeclarated...

Post by alexfru »

Multiple definitions are typically a result of defining non-static variables/functions in .h files that are included in several .c files.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Multiple definition of, error "foo" indeclarated...

Post by Schol-R-LEA »

Looking at the header file isrs.h in your Gitlab repo, I see that the functions in question are in the header itself; this means that they get redefined every time the header is used, which will cause this problem when the linker then has to find which function to attach to which function name. See the wiki page Why function implementations shouldn't be put In header files for a detailed (if tongue in cheek) explanation of the topic, but the short solution is to never put the body of a non-inline function into the header itself.

In this case, since most of these functions are used in several places and are not the sort of tiny ones suited for inserting directly into code repeatedly (i.e., ones under four or five lines of code), simply declaring them as inline probably isn't the best idea. This means you will want to extract them from the header and put them in a source file (e.g., isrs.c would make sense) and add them using the linker. If some of them are used only once, the current C standard does have an inline clause you can use to have the function calls replaced by the body of the function (I can see you've used that in your kernel.h file), which would allow you to keep them in the header (though I would still recommend moving them, as inlining large functions can have odd side effects).

Oh, and for the exception handler, you might want to use inline assembly to insert a hlt instruction in that loop; otherwise, the CPU will be spinning at full tilt, doing nothing but still burning energy and generating excessive heat. And you really, really don't want to declare that as an inline function, because its sole purpose is to be called implicitly by the interrupt handler in multiple places.

I can't say for certain why it isn't finding the defined macros; you do have the terminal.h header included in both of those, but there is no such header file - you have a terminal.c but no terminal.h, which I would have expected to cause a 'missing file' error, too.

I suggest the following as the terminal.h file:

Code: Select all

#ifndef TERMINAL_H
#define TERMINAL_H

#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define LIGHTGRAY 7
#define DARKGRAY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGENTA 13
#define YELLOW 14
#define WHITE 15
#define nl "\r\n"

/* you will want to remove these from 'kernel.h' anyway */
void scroll(void);
void move_csr(void);
void gotoxy(int x, int y);
void clear_screen(void);
void putch(unsigned char c);
void rawputch(unsigned char c);
void println(char *text);
void settextcolor(unsigned char forecolor, unsigned char backcolor);
void init_video(void);
unsigned char getch(void);
char *readln(char *str, int maxnumchars);
char *itoa(int val, int base);

#endif
Similarly for timer.h:

Code: Select all

#ifndef TIMER_H
#define TIMER_H

void timer_phase(int hz);
void timer_handler(struct regs *r);
void timer_install();
void timer_wait(int ticks);
void sleep(int seconds);

#endif
... and serial.h:

Code: Select all

#ifndef SERIAL_H
#define SERIAL_H

void init_serial(void);
int serial_received(void);
unsigned char read_serial(void);
int is_transmit_empty(void);
void write_serial(char a);

#endif
This makes the code more modular and fine-grained. It also means you don't need to include kernel.h everywhere - while most of these files will still need it anyway, others you develop later might not need everything thrown into one big pile.

Finally, you can't use the normal stddef.h and stdint.h as defined by the compiler - those are versions designed for applications, not kernels.
Last edited by Schol-R-LEA on Mon Jan 28, 2019 6:06 pm, edited 1 time in total.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Multiple definition of, error "foo" indeclarated...

Post by Octocontrabass »

Schol-R-LEA wrote:Finally, you can't use the normal stddef.h and stdint.h as definied by the compiler - those are versions designed for applications, not kernels.
Why do you say that? Freestanding headers are intended to be usable everywhere.
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Re: Multiple definition of, error "foo" indeclarated...

Post by deleted8917 »

Octocontrabass wrote:
Schol-R-LEA wrote:Finally, you can't use the normal stddef.h and stdint.h as definied by the compiler - those are versions designed for applications, not kernels.
Why do you say that? Freestanding headers are intended to be usable everywhere.
Correct. I use stddef and stdint without problems, since that libraries are just typedef definitions...
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Multiple definition of, error "foo" indeclarated...

Post by Schol-R-LEA »

Octocontrabass wrote:
Schol-R-LEA wrote:Finally, you can't use the normal stddef.h and stdint.h as definied by the compiler - those are versions designed for applications, not kernels.
Why do you say that? Freestanding headers are intended to be usable everywhere.
Ugh, brain fart time, sorry about that. I'm not sure why I said that.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Re: Multiple definition of, error "foo" indeclarated...

Post by deleted8917 »

I forgot to say that now it works, thanks!
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: Multiple definition of, error "foo" indeclarated...

Post by Schol-R-LEA »

hextakatt wrote:I forgot to say that now it works, thanks!
Good to hear. Do you intend to commit the current version to your repo?
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Post Reply