How do I make a C function visible for functions only in other certains .c files?
Let's suppose I have a foo1 function wich calls other foo2 function (in differents .c files) and I want to call foo1 from my main function, but I want foo2 to be invisible for any function other than foo1, like this:
/**
foo1.c
*/
void foo1()
{
if (condition_is_true){
foo2();
}
}
/**
foo2.c
*/
#include <stdio.h>
void foo2()
{
printf("Hello world!\n");
}
/**
main.c
*/
void foo1(void);
void foo2(void);
int main()
{
foo1();
foo2(); /*unresolved external*/
}
And when compiling
$ cc -omain main.c foo1.c foo2.c
I want the linker to complain "undefined reference to `foo2'".
Usually, if you want to make a function in one .c source code file visible in another .c source file, you place the definition of that function into a .h file and include it into the .c file you want it visible in. For example:
file foo1.c
int somefunc1(some parameters)
{
Do some stuff.
}
file foo1.h
int somefunc1(some parameters);
file foo2.c
#include "foo1.h"
int foo2(Some parameters)
{
Do some stuff.
foo1(asdfasdf)
Do some more stuff.
}
That is generally what you do. However, what you are asking for is the exact opposite. I'm not sure why you want an undefined reference when the linker runs, but the way that you have set your compile, those files will get passed to the linker. So the only thing that you can do is not have foo2.c on the file list. If you are using something from one of the main libraries, it still gets linked in even if you don't specify the include file. For instance:
$$$ ->more test3.c
int main(void)
{
printf("hello world\n");
return(0);
}
$$$ ->clang -std=c11 -Wall -Wextra -o test3 test3.c
test3.c:8:5: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)'
printf("hello world\n");
^
test3.c:8:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'printf'
1 warning generated.
So what you are asking for I don't really think can or should be done.
Related
I'm a beginner learning c. I know that use of word "static" makes a c function and variable local to the source file it's declared in. But consider the following...
test.h
static int n = 2;
static void f(){
printf("%d", n);
}
main.c
#include <stdio.h>
#include "test.h"
int main()
{
printf("%d", n);
f();
return 0;
}
My expected result was that an error message will throw up, since the function f and variable n is local to test.h only? Thanks.
But instead, the output was
2
2
EDIT:
If it only works for a compilation unit, what does that mean? And how do I use static the way I intended to?
static makes your function/variable local to the compilation unit, ie the whole set of source code that is read when you compile a single .c file.
#includeing a .h file is a bit like copy/paste-ing the content of this header file in your .c file. Thus, n and f in your example are considered local to your main.c compilation unit.
Example
module.h
#ifndef MODULE_H
#define MODULE_H
int fnct(void);
#endif /* MODULE_H */
module.c
#include "module.h"
static
int
detail(void)
{
return 2;
}
int
fnct(void)
{
return 3+detail();
}
main.c
#include <stdio.h>
#include "module.h"
int
main(void)
{
printf("fnct() gives %d\n", fnct());
/* printf("detail() gives %d\n", detail()); */
/* detail cannot be called because:
. it was not declared
(rejected at compilation, or at least a warning)
. even if it were, it is static to the module.c compilation unit
(rejected at link)
*/
return 0;
}
build (compile each .c then link)
gcc -c module.c
gcc -c main.c
gcc -o prog module.o main.o
You have included test.h in main.c.
Therefore static int n and static void f() will be visible inside main.c also.
When a variable or function is declared at file scope (not inside any other { } brace pair), and they are declared static, they are local to the translation unit they reside in.
Translation unit is a formal term in C and it's slightly different from a file. A translation unit is a single c file and all the h files it includes.
So in your case, the static variable is local to the translation unit consisting of test.h and main.c. You will be able to access it in main.c, but not in foo.c.
Meaning that if you have another .c file including test.h, you'll get two instances of the same variable, with the same name. That in turn can lead to all manner of crazy bugs.
This is one of many reasons why we never define variables inside header files.
(To avoid spaghetti program design, we should not declare variables in headers either, unless they are const qualified.)
I declared a global static function in one file
a.c
static void Func1(void);
void Func2(void);
void Func1(void) {
puts("Func1 Called");
}
void Func2(void) {
puts("Func2 Called");
}
and accessed it in b.c
#include <stdio.h>
#include "a.c"
void main() {
Func1();
Func2();
}
the program complied successfully, but as per provided information this should give error: undefined reference to Func1. What wrong is happening here?
You don't include a source file in another, you compile and link them together.
In you case, by saying #include "a.c", you're essentially putting the whole content of a.c into b.c and then starting the compilation, so the static functions and their calls are present in the same translation unit. Thus, there is no issue for compiler to find the called function.
Instead, if you do something like
gcc a.c b.c -o a.out //try to compile and link together
you'll see the expected error, as in this case, a.c and b.c will be two separate translation units.
You declare in header files and define in .c files. So you must use header files to represent the variables or functions you defined. Instead if you use .c files then it leads to multiple definitions.I think that is why you can access that global function.
I am having trouble calling an external function I wrote in the Pico editor in linux. The program should call an external function and they are both written in C.
#include????
void calcTax()
float calcfed()
float calcssi()
// stub program
#include"FILE2"???or do I use"./FILE2"// not sure which to use here or what extension the file should have. .c or .h and if it is .h do I simply change the file name to file.h?
#include<stdio.h>
#define ADDR(var) &var
extern void calctaxes()
int main()
{
}
I am using gcc to compile but it will not compile. both files are in the same directory and have the .c extension
I am a new student so bear with me.
Normally, when you want a function in one compilation unit to call a function in another compilation unit, you should create a header file containing the function prototypes. The header file can be included in both compilation units to make sure that both sides agree on the interface.
calctax.h
#ifndef calctax_h_included
#define calctax_h_included
void calctaxes(void);
/* any other related prototypes we want to include in this header */
#endif
Note that extern is not required on functions, only global data. Also, since the function takes no arguments, you should put void in the argument list, and you also need a semi-colon at the end of the prototype.
Next, we can include this header file in the .c file that implements the function:
calctax.c
#include "calctax.h"
void calctaxes(void)
{
/* implementation */
}
Finally, we include the same header file in our main .c file that calls the function:
main.c
#include "calctax.h"
int main(int argc, char **argc)
{
calctax();
return 0;
}
You can compile and link these together with
% gcc -o main main.c calctax.c
Normally you don't want to include .c implementation files. The normal thing to do is have two source files that you build into objects:
cc -o file1.o file1.c
cc -o file2.o file2.c
And then link them into an executable at the end:
cc -o example file1.o file2.o
To allow calling functions between the two .c files, you create a header (.h) file that has function declarations for everything you're interested in sharing. For you, that might be something like header.h, containing:
void calcTax(void);
float calcfed(void);
float calcssi(void);
Then, just #include "header.h" from the implementation files where you need to know about those functions.
I have a family of executables pieced together from a set of .o files. There's some reusable ones, and then usually a couple of executable specific modules. One of the reusable pieces wants to provide a sort of "application hook". But many of the executables just do a standard no-op thing. While a couple of others actually want to define interesting behavior for said hook.
What would be ideal, is if there was a way to provide a standard default version of the function, which the linker would use if none of the other .o files defined said function, but if they did, use the others.
Is there any way/technique to approximate this sort of thing with just straight C?
If you're using GCC as your compiler, then you can declare the replaceable functions like this:
void foo() __attribute__ ((weak));
Here's an example on how this works. In your main.c file:
#include <stdio.h>
void foo()__attribute__ ((weak))
{
printf("%s", "Hidden foo\n");
}
int main()
{
foo();
return 0;
}
In another file, foo.c:
#include <stdio.h>
void foo()
{
printf("%s", "foo\n");
}
Now when you only compile, link and run main.c, you'll get:
gcc main.c -o main
./main
Hidden foo
If you instead also compile foo.c, you'll get:
gcc main.c foo.c -o main
./main
foo
The weak version of foo() was replaced.
On a real setup, you would probably use a header file to provide the function prototypes:
void foo();
and then implement the weak version of those functions like this:
__attribute__ ((weak)) void foo()
{
// ...
}
You could also use a macro to make this a bit more readable:
#define WEAK_SYMBOL __attribute__ ((weak))
So that you'll get:
WEAK_SYMBOL void foo() { /* ... */ }
I need to include file_1.c into main.c. In file_1.c, I currently have multiple functions. If I want to call these functions in main.c, what do I need to do? I have #include"file_1.c" in my main program.
Use standard approach by making header file
#include"file_1.h"
you will have to compile this "file_1.c" together with main.c and make one executable
because function calls are need in run time.
Try this :
create a header file file_1.h
#ifndef _FILE_H
#define _FILE_H
void foo(int );
#endif
give all the declaraion of function and struct definitions (if any) or any global variables
then in file_1.c will contain actual defintion of function
//file_1.c
#include "file_1.h"
#include <stdio.h>
void foo(int x)
{
printf("%d\t",x);
}
//main.c
#include "file_1.h"
int main()
{
int x=10;
foo(x);
return 0;
}
include header file file_1.h in both (main.c and file_1.c) the c files
In gcc
gcc -Wall main.c file_1.c -o myexe.out
Why do you think you need to do this?
Normally you would add the declaration of functions in file_1.c into file_1.h and include that in main.c.
When you link the program, you just need to include both main.c and file_1.c (which then includes the definitions of the functions) on the command line.