So I'm making a function called reboot, but when I define it the compiler gives an error like the function is already defined.
Here is bios.c:
#include "bios.h"
#include <stdint.h>
#include <libasm/asm.h>
void reboot()
{
uint8_t good = 0x02;
while (good & 0x02)
good = EmeraldASM_inb(0x64);
EmeraldASM_outb(0x64, 0xFE);
asm volatile("hlt");
}
here is bios.h :
#ifndef BIOSPOWER_H
#define BIOSPOWER_H
#pragma once
void reboot();
extern void shutdown();
#endif
here is the compiler error: /home/abbix/Documents/Projects/emerald/src/firmware/bios.c:5: multiple definition of `reboot'; src/firmware/bios.o:/home/abbix/Documents/Projects/emerald/src/firmware/bios.c:5: first defined here
Here is my Makefile:
https://pastebin.com/xCcQEtx3
The problem was that my assembly file had the name bios.asm, so it created two bios.o that was what caused the error (thanks to Eric Postpischil)
Related
I have the problem, that in CCS I encounter unexpected redefenition errors if I include headers.
Minimal example:
// main.c
#include "test.h"
int main(void)
{
init();
return 0;
}
with
// test.h
#ifndef TEST_H_
#define TEST_H_
int var;
void init();
#endif /* TEST_H_ */
and
// test.c
#include "test.h"
void init()
{
var=0;
}
I get
error #10056: symbol "_var" redefined: first defined in "./main.obj";
redefined in "./test.obj"
on compilation. I'm pretty sure this should work in any C using IDE.
What do I miss?
" I'm pretty sure this should work in any C using IDE". No it doesn't.
Every time you include test.h in a C file, the variable var is not only declared but also defined, hence the compilation error.
Include guards are not designed to avoid multiple definitions across translation units, but more to adress multiple inclusions of the same header file in a single translation unit.
See for example https://fr.wikipedia.org/wiki/Include_guard
The proper way to adress this issue is to only declare your variable in the header file:
extern int var;
and then define the variable only once in a C file (without extern).
int var;
I have a stupid problem and I don't see where it comes from. I took care of using #ifndef directive to make sure all my #include are not redefined. Sadly for three of them that's happening. Here my multiple files arch :
t_include.h
#ifndef T_INCLUDE_H_
#define T_INCLUDE_H_
/* Project specific dependencies*/
#include "utilities.h"
#include "fsp_function.h"
#include "ti/csl/csl_tsc.h"
#include "ti/csl/csl_cache.h"
#include "ti/csl/csl_cacheAux.h"
#include "ti_sp_complex_convolution_A_input1.h"
#include "ti_sp_complex_convolution_A_input2.h"
#include "to_sp_complex_convolution_A_output.h"
#endif /* T_INCLUDE_H_ */
t_function.h
#ifndef T_FUNCTION_H_
#define T_FUNCTION_H_
#include "t_include.h"
/*output vector*/
#define INPUT1A_LENGTH 5000
#define INPUT2A_LENGTH 2800
#define OUTPUTA_LENGTH 2202
extern FLOAT32 sp_complex_convolution_A_output_thales[OUTPUTA_LENGTH];
/*misc parameter*/
#define CPU_CLOCK_KHZ 1400000
#define CPU_CLOCK_MS 1/CPU_CLOCK_KHZ
#define FIR_NB_MACS INPUT1A_LENGTH * OUTPUTA_LENGTH /* FIR algorithm complexity */
#define NB_OF_REP 10
#define UMA_L2CACHE_L1DCACHE 0
/* Project specific types */
typedef struct{
ect...
And now c file only include t_function.h :
t_function.c
/* Dependencies */
#include "t_function.h"
FLOAT32 sp_complex_convolution_A_output_thales[OUTPUTA_LENGTH];
/* API */
etc...
And t_main_function.c
/* dependencies */
#include "t_function.h"
void main(void) {
etc...
It should work but during linking here the errors comming :
<Linking>
error #10056: symbol "sp_complex_convolution_A_output" redefined: first defined in "./TEST/t_function.obj"; redefined in "./TEST/t_main_function.obj"
error #10056: symbol "sp_complex_convolution_A_input2" redefined: first defined in "./TEST/t_function.obj"; redefined in "./TEST/t_main_function.obj"
error #10056: symbol "sp_complex_convolution_A_input1" redefined: first defined in "./TEST/t_function.obj"; redefined in "./TEST/t_main_function.obj"
error #10056: symbol "sp_complex_convolution_A_output_thales" redefined: first defined in "./TEST/t_function.obj"; redefined in "./TEST/t_main_function.obj"
>> Compilation failure
error #10010: errors encountered during linking; "CONVOLUTION_COMPLEX.out" not built
So the error only com from three symbol sp_complex_convolution_A_output, sp_complex_convolution_A_input1 and sp_complex_convolution_A_input2 Which are defined in their own .h which is also protected by #ifndef directives:
ti_sp_complex_convolution_A_input1.h
#ifndef __TI_SP_COMPLEX_CONVOLUTION_A_INPUT1_H_
#define __TI_SP_COMPLEX_CONVOLUTION_A_INPUT1_H_
FLOAT32 sp_complex_convolution_A_input1[2 * 2500] = {
etc...
And the same for the other two...
So I really don't know why it is happening.
Thx for helping
Definitions like:
FLOAT32 sp_complex_convolution_A_output_thales[OUTPUTA_LENGTH];
should go into a source file.
The header files should contain only declarations like:
extern FLOAT32 sp_complex_convolution_A_output_thales[OUTPUTA_LENGTH];
As a rule of thumb, do no put anything that allocates memory into header files.
I have a driver which is known to compile on somebody else's machine, however, it's not on mine (a toolchain/compiler difference?). I'm getting error: implicit declaration of function '__REG' [-Werror=implicit-function-declaration]. Here's the code which is causing it:
enum {
#define __REG(a,b2,b1,c,d,e,f) a,
#include "mycodec-i2c.h"
#undef __REG
};
And then later on in the code...
static const mycodec_reg_t mycodec_data[]=
{
#define __REG(a,b2,b1,c,d,e,f) c,
#include "mycodec-i2c.h"
#undef __REG
};
Is that really legal to do in C? How do I get around it?
The header file contains a whole bunch of register definitions.
// screen.h
#ifndef screen_h
#define screen_h
#define MAC 1
#define WIN 2
#define LNX 3
#ifdef PLATFORM
# undef PLATFORM
#endif
#define PLATFORM MAC
void screen_init();
#endif
// screen.c
#include <string.h>
#include <stdlib.h>
#include "screen.h"
#if PLATFORM == MAC
#include <curses.h>
void screen_init(){
erase();
}
#endif
I don't understand why it is not seeing my prototype in screen.h
Any suggestions/hints are appreciated!
ISO/IEC 9899:TC2 - 6.2.1.2:
A function prototype is a declaration of a function that declares the types of its parameters.
An empty argument list in a function declaration indicates that the number and type of parameters is not known. You must explicitly indicate that the function takes no arguments by using the void keyword. Otherwise your function declaration does not count as a valid prototype.
void screen_init(void);
I met this similar error minutes ago. After i'd added the relatived function declaration in head file, error's gone.
Also, some said that canceling the compile option '-Wmissing-prototypes' should work, but i didn't have tried that. Good luck.
I just had this problem today.
I defined a function that just used internally
void func(void) {
}
int main(void) {
func();
}
This will give me that warning.
I had to add the prototype at the beginning of the file to get rid of the warning.
void func(void);
void func(void) {
}
int main(void) {
func();
}
I'm trying to understand how global variables and functions work in C. My program compiles and works fine with gcc, but does not compile with g++. I have the following files:
globals.h:
int i;
void fun();
globals.c:
#include "stdlib.h"
#include "stdio.h"
void fun()
{
printf("global function\n");
}
main.c:
#include "stdlib.h"
#include "stdio.h"
#include "globals.h"
void myfun();
int main()
{
i=1;
myfun();
return 0;
}
And finally, myfun.c:
#include "stdlib.h"
#include "stdio.h"
#include "globals.h"
void myfun()
{
fun();
}
I get the following error when compiling with g++:
/tmp/ccoZxBg9.o:(.bss+0x0): multiple definition of `i'
/tmp/ccz8cPTA.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Any ideas why? I would prefer to compile with g++.
Every file you include globals.h from will define "int i".
Instead, put "extern int i;" into the header file and then put the actual definition of "int i = 1;" in globals.c.
Putting header guards around globals.h would be sensible too.
Edit: In answer to your question its because a #include works kind of like a cut and paste. It pastes the contents of the included file into the c file that you are calling include from. As you include "globals.h" from main.c and myfun.c you define int i = 1 in both files. This value, being global, gets put into the table of linkable values. If you have the same variable name twice then the linker won't be able to tell which one it needs and you get the error you are seeing. Instead by adding extern on the front in the header file you are telling each file that "int i" is defined somewhere else. Obviously, you need to define it somewhere else (and ONLY in one place) so defining it in globals.c makes perfect sense.
Hope that helps :)
I would add an include guard in your globals file
#ifndef GLOBALS_H
#define GLOBALS_H
int i;
void fun();
#endif
Edit: Change your globals to be like this (using extern as the other answer describes)
globals.h
extern int i;
extern void fun();
globals.c
#include "stdlib.h"
#include "stdio.h"
int i;
void fun()
{
printf("global function\n");
}
I compiled it with
g++ globals.c main.c myfun.c
and it ran ok
Several things wrong here; several other things highly recommended:
globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H
extern int my_global;
#ifdef __cplusplus
extern "C" {
#endif
void fun();
#ifdef __cplusplus
}
#endif
#endif
/* GLOBALS_H */
globals.c:
#include <stdlib.h>
#include <stdio.h>
#include "globals.h"
int my_global;
void fun()
{
printf("global function: %d\n", my_global);
}
main.c:
#include <stdlib.h>
#include <stdio.h>
#include "globals.h"
void myfun();
int main()
{
my_global=1;
myfun();
return 0;
}
void myfun()
{
fun();
}
You should declare "extern int myvar" in your header, and actually allocate "int myvar" in one and only one .c file.
You should include "globals.h" in every file that uses "myvar" - including the file where it's allocated.
Especially if you're planning on mixing C and C++ modules, you should use 'extern "C"' to distinguish non-C++ functions.
System headers should be "#include <some_header.h>"; your own headers should use quotes (#include "myheader.h") instead.
Short variable names like "i" might be OK for a strictly local variable (like a loop index), but you should always use longer, descriptive names whenever you can't avoid using a global variable.
I added a "printf" for my_global.
'Hope that helps!
I had this problem when porting some old C code to C++. The problem was it was a project that was connected to a database, and i wanted to port the database to c++ but not the rest. The database pulled in some C dependencies that couldn't be ported, so i needed the C code that overlapped both the database and the other project to compile in g++ as well as gcc...
The solution to this problem is to define all variables as extern in the .h file. then when you compile in either gcc or g++ it will report symbols missing in the .c files. So edit the .c files in the error messages and insert the declaration into all the .c files that need the variables. Note: you may have to declare it in multiple .c files, which is what threw me and why I was stuck on this problem for ages.
Anyway this solved my problem and the code compiles cleanly under both gcc and g++ now.