Function declared in header not accessible in main file - c

I have a file structure as follows:
interface.h --> interface.c
|
|
effects.h --> effects.c
|
|
main
However, functions declared in effects.h are not accessible in main.
Code snippets :
main :
#include "interface.h"
#include "effects.h"
void setup() //Initialize all variables here
{
....
turnoff();
};
effects.h :
#ifndef EFFECTS
#define EFFECTS
void turnoff();
#endif
effects.c :
#include "interface.h"
#include "effects.h"
void turnoff()
{
....
};
interface.h :
#ifndef INTERFACE
#define INTERFACE
....
#endif
Error message : In function ``loop':undefined reference to ``turnoff()'
The error message doesnt make sense as loop function is empty !

You need to compile and link all 3 .c files together. With gcc it's as simple as
gcc main.c interface.c effects.c -o executable_name

I think the IDE wants *.cpp files instead of *.c files.
Anyway you should change the settings under file->preferences to get verbose compiler output. Usually this gives some hints. At least it shows you the temporary directory that contains the files that are actually compiled. This in turn allows much more precise analysis of the issue.

From the latest response, I feel that effects.c is not part of the compilation. I am not aware of the development environment, but from the available data, this is my observation.

what are the flags you are using?
maybe you need to declare your functions as extern explicitly?
extern void turnoff();

Related

multiple definitions of main --> how to add only some functions from another header?

In C I get the linker error multiple definition of `main'. Yes, that is true but:
Why does the linker try to include the second (ext.c) main function although I have just included the header ext.h? I'd expect, the linker only links the functions whose prototypes have been found or which are needed by the initial main?
How can I solve this that
a) test compiles and gets linked without issues (just use the func() from ext.c) and
b) also ext.c can be compiled and linked as separate application?
The (example) code:
//file: test.c
#include "/home/stefanm/test/test.h"
void main (int argc, char * argv[])
{
uint8_t var = 123;
printf ("main(): var= %i\n", var);
func (var);
}
//file: test.h
#ifndef TEST_H
#define TEST_H
#include <the rest>
#include "/home/stefanm/test/ext.h"
#endif
...and the external module:
//file: ext.c
#include "/home/stefanm/test/ext.h"
uint8_t func (uint8_t i){
printf ("func(): Variable i is %i", i);
return 0;
}
void main () {
printf ("ext main func");
}
//file: ext.h
#ifndef EXT_H
#define EXT_H
#include "all needed headers"
uint8_t func (uint8_t);
#endif
I call the compiler with gcc test.c ext.c -o test
Your external module should not have main() because it's a module and not an application. You should just move main() from your module to a separate file:
//file: app.c
#include "/home/stefanm/test/ext.h" // <-- BTW, using absolute paths is not a good idea
void main () {
//use function from ext here
printf ("app main func");
}
And then compile your application like this:
gcc app.c ext.c
and your test like this:
gcc test.c ext.c
In C, you can only have one definition of a function in all of the files you link into your executable. There's no good way to tell the compiler "I want to use this main() and not all the others". (There's a bad way, using macros, but it would be messy).
If you want to use a function with two different main() functions, put it in a separate file.
I suppose your compile/link call goes like
gcc test.c ext.c
In this case, test.c and ext.c (resp., to be exact, the .o files created out of them) are peers, i. e. on the same level. How should the linker know which version of the symbol main to take and which to discard? The linker doesn't know about the include files used.
In the case of a main function, the correct way to go is to have exactly one of them in your project.
For any other function where you have this requirement, there are several ways to go:
Either, you could declare one of them as "weak". It will be discarded when there is a "strong one".
Or you put your function into a library, e. g. libext.a. If you link that with -ext, only the object files which define symbols which are undeined are taken out of it. But then again, name clashes can occur if another name defined by that object file is defined already. So it is the best to only define as few symbols per object file as possible.

"Multiple definition", "first defined here" errors

I have 3 projects: Server, Client and Commons. Making header & source pairs in Commons doesn't cause any problems and I can access the functions freely from both Server and Client.
However, for some reason making additional source/header files within Server or Client project always causes multiple definition of (...) and first defined here errors.
Example:
commands.h (in root dir of the Client project)
#ifndef COMMANDS_H_
#define COMMANDS_H_
#include "commands.c"
void f123();
#endif /* COMMANDS_H_ */
commands.c (in root dir of the Client project)
void f123(){
}
main.c (in root dir of the Client project)
#include "commands.h"
int main(int argc, char** argv){
}
Errors:
make: *** [Client] Error 1 Client
first defined here Client
multiple definition of `f123' commands.c
Cleaning, rebuilding index, rebuilding projects doesn't help. Neither does restarting the computer.
The problem here is that you are including commands.c in commands.h before the function prototype. Therefore, the C pre-processor inserts the content of commands.c into commands.h before the function prototype. commands.c contains the function definition. As a result, the function definition ends up before than the function declaration causing the error.
The content of commands.h after the pre-processor phase looks like this:
#ifndef COMMANDS_H_
#define COMMANDS_H_
// function definition
void f123(){
}
// function declaration
void f123();
#endif /* COMMANDS_H_ */
This is an error because you can't declare a function after its definition in C. If you swapped #include "commands.c" and the function declaration the error shouldn't happen because, now, the function prototype comes before the function declaration.
However, including a .c file is a bad practice and should be avoided. A better solution for this problem would be to include commands.h in commands.c and link the compiled version of command to the main file. For example:
commands.h
#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123(); // function declaration
#endif
commands.c
#include "commands.h"
void f123(){} // function definition
I had a similar issue when not using inline for my global function that was included in two places.
You should not include commands.c in your header file. In general, you should not include .c files. Rather, commands.c should include commands.h. As defined here, the C preprocessor is inserting the contents of commands.c into commands.h where the include is. You end up with two definitions of f123 in commands.h.
commands.h
#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123();
#endif
commands.c
#include "commands.h"
void f123()
{
/* code */
}
Maybe you included the .c file in makefile multiple times.
I am adding this A because I got caught with a bizarre version of this which really had me scratching my head for about a hour until I spotted the root cause. My load was failing because of multiple repeats of this format
<path>/linit.o:(.rodata1.libs+0x50): multiple definition of `lua_lib_BASE'
<path>/linit.o:(.rodata1.libs+0x50): first defined here
I turned out to be a bug in my Makefile magic where I had a list of C files and using vpath etc., so the compiles would pick them up from the correct directory in hierarchy. However one C file was repeated in the list, at the end of one line and the start of the next so the gcc load generated by the make had the .o file twice on the command line. Durrrrh. The multiple definitions were from multiple occurances of the same file. The linker ignored duplicates apart from static initialisers!
This error can also occur if the definitions are "header file only".
Example :
foo.h :
#ifndef FOO
#define FOO
int myFunc(int a) {
return a+2;
}
#endif
// There is no foo.c
// Main source files
file1.c :
#include "Foo.h"
<some code>
file2.c :
#include "Foo.h"
<some code>
Now both file1.c and file2.c contains definition of myFunc(). This will cause linker error when they are getting linked to same library.

How to conditional compile main() in C?

I'm working on a small open source project in C where I'm trying to use a test framework with C (the framework is min_unit).
I have a foo.h file with prototypes, and foo.c, with the implementation.
In my test file, tests.c, I have
#include "../test_framework/min_unit.h"
#include "foo.c"
... test cases ...
the problem is, because I have a main() function in foo.c (which I need to compile it), I can't compile tests.c because I get an error that states
note: previous definition of ‘main’ was here
int main() {
My question is, is there a way to make it so that the main() function in foo.c is conditional, so that it does not compile when I'm running tests.c? It's just annoying to have to remove and add main over and over.
The easiest way to use conditional compilation is to use #ifdef statements. E.g., in foo.c you have:
#ifdef NOT_TESTING //if a macro NOT_TESTING was defined
int main() {
//main function here
}
#endif
While in test.c, you put:
#ifndef NOT_TESTING //if NOT_TESTING was NOT defined
int main() {
//main function here
}
#endif
When you want to compile the main function in foo.c, you simply add the option -DNOT_TESTING to your compile command. If you want to compile the main function in test.c, don't add that option.
Haven't you try the use of pre-processor compiler conditions? May be you've tried but it doesn't work, hum?
Anyway, you probably should:
1- Define a token at top of "tests.c" class file like:
#defined foo_MIN_UNIT_TEST
2- Surround your "main() { ... } " method in "foo.c" class file with #ifndef / #endif like:
#ifndef foo_MIN_UNIT_TEST //consider using #ifndef not #ifdef!!!
int main()
{ ... }
#endif
3- This way, when you compile your unit test files, the main() method of foo.c will not be included in compile time and the only main() method of tests will be available to compiler.
For further reading: http://www.cprogramming.com/
Regards.

Calling #define from another file

This is my code. I have file1.c and file2.c. I want to call the MESSAGE from file2.c but I can't seem to do it. I am newbie in C so I really don't know what to do. I researched already but, I can't seem to find a specific answer. Thankyou.
#define MESSAGE "this is message!"
helloworld(){
printf("%s",MESSAGE);
getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file2.c"
int main(void)
{
helloworld();
}
There are a few misconceptions you have: First of all the concept of "calling" a macro. It's not possible, even if a macro looks like a function it's not a function and macros are not actually handled by the compiler. Instead macros are part of a separate language that is handled by a preprocessor, which takes the source file and modifies it to generate a translation unit that the compiler sees. (For more information about the difference phases of "compilation" see e.g. this reference.)
The preprocessor does this by basically doing a search-replace in the input source file: When it sees a macro "invocation" it simply replaces that with the "body" of the macro. When it sees an #include directive, it preprocesses the file and then puts the content in place of the directive.
So in your code, when the preprocessor sees the macro MESSAGE it is literally replaced by "this is message!". The actual compiler doesn't see MESSAGE at all, it only sees the string literal.
Another misconception is how you use the #include directive. You should not use it to include source files. Instead you compile the source files separately (which creates object files) and then link the generated object files together with whatever libraries are needed to form the final executable.
To solve the problem of macros (and other declarations) being available to all source files, you use header files. These are like source files, but only contains declarations and macros. You then include the header file in both source files, and both source files will know about the declarations and macros available in the header file.
So in your case you should have three files: The main source file, the source file containing the function, and a header file containing the macro and the function declaration (also known as a prototype). Something like
Header file, e.g. header.h:
// First an include guard (see e.g. https://en.wikipedia.org/wiki/Include_guard)
#ifndef HEADER_H
#define HEADER_H
// Define the macro, if it needs to be used by all source files
// including this header file
#define MESSAGE "this is message!"
// Declare a function prototype so it can be used from other
// source files
void helloworld();
#endif
Main source file, e.g. main.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
int main(void)
{
// Use the macro
printf("From main, MESSAGE = %s\n", MESSAGE);
// Call the function from the other file
helloworld();
}
The other file, e.g. hello.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
void helloworld(void)
{
printf("Hello world!\n");
printf("From helloworld, MESSAGE = %s\n", MESSAGE);
}
Now, if you use a command-line compiler like gcc or clang then you can simply build it all by doing e.g.
$ gcc -Wall main.c hello.c -o myhello
That command will take the two source files, main.c and hello.c and run the preprocessor and compiler on them to generate (temporary) object files. These object files are then linked together with the standard C library to form the program myhello (that's what the option -o does, names the output file).
You can then run myhello:
$ ./myhello
From main, MESSAGE = this is message!
Hello world!
From helloworld, MESSAGE = this is message!
In your file1.c, MESSAGE is a preprocessor macro, which means the text MESSAGE will be replaced with the string "this is message!". It is not visible outside the file. This is because in C, translation units are the final inputs to the compiler, and thes translation units already have all of preprocessor macros replaced by the tokens of the corresponding argument.
If you want to have a common variable, you should declare the variable as extern in a .h header file, and then #include the file where you need to use it.
see Compiling multiple C files in a program
You have to put your #define in a .h file and include it in .c files where you want to use it.
You can write the files as below and compile the code as i mention in the following steps.
file1.h
#ifndef _FILE1_H
#define _FILE1_H
#define MESSAGE "this is message!"
extern void helloworld();
#endif
file1.c
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
file2.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
return 0;
}
For compiling,
gcc -Wall file1.c file2.c -o myprog
./myprog
Here is code try this:
In File1.C
#define FILE1_C
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
In File2.C
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
}
In File1.h
#ifdef FILE1_C
#define MESSAGE "this is message!"
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN helloword()

Duplicate header files throughout source files?

// File foo1.c :
#include <stdio.h> // once
void foo1(void);
void foo1(void){
puts("foo1");
}
// File foo2.c :
#include <stdio.h> // again
void foo2(void);
void foo2(void){
puts("foo2");
}
// File foomain.c :
#include <stdio.h> // yet again
void foo1(void); // again
void foo2(void); // again
int main(void){
foo1();
foo2();
puts("foomain");
return 0;
}
// create object files
gcc -fPIC foo1.c -o foo1.o // 1 stdio.h
gcc -fPIC foo2.c -o foo2.o // 1 stdio.h
// create shared library
gcc -fPIC -shared foo1.o foo2.o -o foo.so // foo.so contains stdio.h 2 times ?
// build entire program
gcc foo.so foomain.c -o foomain // foomain contains 1 stdio.h plus the 2 from foo.so ?
Why does the entire program contain 3 stdio.h ? Seems redundant, why not just 1 ? Shouldn't the compiler need only 1 ?
It makes sense for the object files to contain a prototype but why do they have to be specified again in foomain.c ? Shouldn't the compiler know they are already specified in foo.so ?
That's because each file is compiled separately, so each time the compiler should know the signatures of all functions used to perform compile-time checks. So, each file has to contain all declarations used, which are included by the preprocessor before the file is compiled.
If you look at the top of most header files they have an include guard to stop double inclusion.
#ifndef FOO
#define FOO
#endif
See Include Guard for more information.
The #include lines are not actually a part of the compiler, but the C preprocessor.
What the preprocessor does with #include lines is to actually include the file into the source, and creates a new temporary file containing the contents of your file with the #include line replaced by the contents of the file being included.
You don't actually need the include file at all, if all you are doing is calling functions. You might get warnings about the functions not being declared, but those can be adding the prototypes for those functions yourself. For example, in your main source file you only use puts, instead of including <stdio.h> you can add a prototype like this:
int puts(const char *s);
However, <stdio.h> also defines some structures (like the FILE structure) and declares some variables (like stdout) and if you use any of those you need the header file as well.
You can use include guards as #Jeff suggested or just put #pragma once at the top of each header.

Resources