For debugging reasons i created the following code example: There is a function a() which is called by the function b(). I want to know the name of the function which calls a(). So i created the code below which is working fine:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
uint8_t a(uint8_t k)
{
printf("function: a\n");
return k;
}
uint8_t a_debug( uint8_t j, char const *caller_name)
{
uint8_t rtv;
printf("a was called by %s\n", caller_name);
rtv = a(j);
return rtv;
}
#define a(x) a_debug(x,__func__)
void b()
{
uint8_t asdf;
asdf = a(5);
printf("asdf = %u", asdf);
}
int main(int argc, char **argv)
{
b();
return 0;
}
In a bigger software project with several c- and h-files I pasted the code
uint8_t a_debug( uint8_t j, char const *caller_name)
{
uint8_t rtv;
printf("a was called by %s\n", caller_name);
rtv = a(j);
return rtv;
}
#define a(x) a_debug(x,__func__)
right below the function a() to debug the function a(). I can build and execute the software-project but the function a_debug() is never entered. Instead of the function a() is directly executed. In which file or exactly where do I have to define the preprocessor directive #define a(x) a_debug(x,__func__) so that the compiler will displace a() with a_debug() function?
Preprocessor directives operate only in the translation unit where they appear.
A translation unit is the source file being compiled, including all the files it includes. To use a preprocessor macro, it must be defined in the translation unit. The way this is usually done is that a source file containing some functions named foo or related to some category or idea foo are defined in a file named foo.c, and declarations for those functions are put in a file named foo.h. The header file foo.h should provide whatever preprocessor macros, declarations, and other things are needed to use the facilities provided by foo.c.
To start, you can put your new function a_debug in the source file that contains a. Also, you can simplify it; there is no need for the variable rtv:
uint8_t a_debug(uint8_t j, char const *caller_name)
{
printf("a was called by %s.\n", caller_name);
return a(j);
}
Then, in the header file that declares a, you need to add two things. First, a declaration for a_debug:
uint8_t a_debug(uint8_t, char const *);
Second, a definition for the macro a:
#define a(x) (a_debug((x), __func__))
However, this is going to cause a problem. The source file defining a should include its own header file. (One reason for this is to allow the compiler to check for errors such as function declarations not matching function definitions.) But when it includes the header file, that will define the a macro, and then, when the function a is defined, the definition will be altered by the macro replacement, and the compiler will complain. One way around this is to put #undef a in the source file that defines a, after it includes its header file.
Also, since a_debug is so simple, you can define it as a static inline function in the header. Instead of putting the definition shown above in the source file and its declaration in the header file, put this in the header file:
static inline uint8_t a_debug(uint8_t j, char const *caller_name)
{
printf("a was called by %s.\n", caller_name);
return a(j);
}
Related
I am trying to enable a set of functions from a header only if a macro is defined
I define the macro before including anything and it reaches the .h file and highlights the proper functions, but it does not reach the .c file so I can call the functions with the right prototypes but they have no definition since the .c file does not see I defined the macro
Is there some way to get this to work without having to stuff all of the .c code inside the .h file?
example:
test.h:
#ifdef _ENABLE_
int enabled_function(int a, int b);
#endif
test.c:
#ifdef _ENABLE_
int enabled_function(int a, int b)
{
return a + b;
}
#endif
main.c:
#define _ENABLE_
#include "test.h"
int main()
{
printf("%d", enabled_function(10, 10));
}
you need to use conditional compilation in both header and C file
in header file:
#define SOMETHING
#ifdef SOMETHING
int a(int);
int b(int);
int c(int);
#endif
In the C file:
#include "header_file_with_SOMETHING_declaration.h"
#ifdef SOMETHING
int a(int x)
{
/* ... */
}
int b(int x)
{
/* ... */
}
int b(int x)
{
/* ... */
}
#endif
Your source files test.c and main.c represent separate translation units. The macro definitions declared in one are not visible to the other.
Declarations that need to be visible across multiple translation units, whether of macros or of anything else, generally should go into header files that all translation units wanting them #include. It is possible to have a header that serves the sole purpose of defining macros that control configuration options, that you would create or update prior to compilation. There are tools that automate that sort of thing, but they are probably much heavier than you require for your purposes right now.
For macros specifically, most compilers also offer the option of specifying macro definitions via compiler command-line arguments.
Either way, no, your definition in main.c of macro _ENABLE_ will not be visible in test.c. (And no, you shouldn't merge test.c into test.h.)
But you should also consider whether you actually need any of that. Certainly there are use cases for cross-translation-unit build-time configuration, but what you present does not look like one of them. It is rarely very useful to suppress the compilation of a function just because you know you're not going to call it. it is usually better to either remove it altogether or to leave it, uncalled. In the latter case, your linker might even be smart enough to omit unused functions from the final binary.
"Is there some way to get this to work without having to stuff all of the .c code inside the .h file?"
and from comments...
"...but I wish to be able to define the macro in my main file and have it be visible from the .c file too
So, you are asking to #include one .c file into another .c file. This is doable with caution. But because a .c file containing the main() function cannot be #include into another .c file without invoking a multiply defined symbol error for main(...), it has to be the other way around. That is a dedicated .c file (eg. enabled.c) could be created that contains all of the #defines function prototypes and definitions. This .c file can then be #included into main.c to hopefully satisfy a variation of what you are looking for.
Following is tested source code that does this:
enable.c
#define _ENABLE_
//test criteria - then create prototype of enabled_function
#ifdef _ENABLE_
static int enabled_function(int a, int b);
#endif
#ifdef _ENABLE_
static int enabled_function(int a, int b)
{
return a + b;
}
#endif
static int use_enabled_function(int a, int b);
//This will be created with or without _ENABLE_, but its
//definition changes based on whether _ENABLE_ exists or not.
static int use_enabled_function(int a, int b)
{
#ifdef _ENABLE_
return enabled_function(a, b);
#elif
return -1;
#endif
}
main.c
#include "enable.c"
int main(void)
{
//test criteria - then use enabled_function
#ifdef _ENABLE_ //must include test for existence before using
printf("%d\n", enabled_function(10, 10));
#endif
//no need to test criteria here (tested internally)
printf("%d\n", use_enabled_function(10, 10));
return 0;
}
I am using STM32F103 and and Keil for the Compiler. Here is my summary code:
There is a header file like abc.h and abc file has a static variable. abc.h is like that:
static uint8 a;
And there is a function in another header file which named abcd.h and that changes the a' s value.
abcd.h header file is like that.
include "abc.h"
void foo()
{
a = 0x0A;
}
My issue is that:
When I call the "foo" fuction in main "a" is turn to zero even if I assign the "a" variable to 0x0A in "foo()" function. By the way, If I define the "a" variable with extern and the problem does not occured. I mean "a" is get 0x0A value.
Is there anyone the help me why does this problem occur.
Some rules of thumb:
Never declare global variables. (extern ones)
Never declare variables inside header files.
static variables are per definition not global, but could be "file scope" - that is, visible to the file they are declared inside. Or more accurately, visible inside the translation unit they are declared inside, a translation unit meaning a specific .c file and all the headers that .c file includes.
So if you declare a static variable in a header, which is included by two different .c files, then you end up with multiple local copies of the variable. If you are lucky, you get a linker error, but the linker may as well attempt some internal "name mangling". The very meaning of static is to prevent access to the variable by other files.
The best solution to this is to use setter/getter functions:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
uint8_t get_a (void);
void set_a (uint8_t n);
#endif
-
// abc.c
#include "abc.h"
static uint8_t a;
uint8_t get_a (void)
{
return a;
}
void set_a (uint8_t n)
{
a = n;
}
That is how you should be doing in the vast majority of cases. Using extern should be avoided, but for the rare cases when you have to use it, then use it like this:
// abc.h
#ifndef ABC_H // always use "header guards"
#define ABC_H
extern uint8_t a;
#endif
-
// abc.c
#include "abc.h"
uint8_t a;
I have two files.
The first file contains the function prototype and the main function calls myfunc with only one argument:
int myfunc (int x);
int main ()
{
int x =5;
myfunc(x);
}
and the second file contains the function definition but with 2 arguments:
int myfunc (int x, int y)
{
return x+y;
}
When I tried to compile this two files using GCC I got no errors or warnings.
How to force GCC to warn about something like this??
Put your prototypes in a header file, and #include the header file in all source files which use the functions.
GCC compiles each file independently, so it cannot know that the definition of the function does not correspond to the declaration unless the declaration is also included in the file with the definition.
It should look like this:
myfunc.h
#ifndef MYFUNC_H
#define MYFUNC_H
int myfunc (int x);
#endif
myfunc.c
#include "myfunc.h"
int myfunc (int x, int y)
{
return x+y;
}
main.c
#include "myfunc.h"
int main ()
{
int x =5;
myfunc(x);
}
Because the two source files are two different translation units that are compiled completely separately, it's impossible for the compiler to know about this. And as C symbols doesn't really have information about arguments, the linker can't warn about this either.
The only solution is to put function prototypes in header files that are included in all relevant source files.
For example: If I have two .h files
process1.h and process2.h
and they contain two function with different output variables.
process1.h:
function(int var)
{
return 2*var;
}
process2.h:
function(int var)
{
return 10*var;
}
Can this be done in main.c:
int main()
{
int a = 2;
#include "process1.h"
printf("%d",function(a)); //output is 4
EXCLUDE #INCLUDE "process1.h" ????? <----can this be done in any way??
#include "process2.h"
printf("%d",function(a)); //output is 20
}
No, you cannot "un-include" a file. Think of all the preprocessor directives (lines starting with #) as happening before the actual C compiler even sees the source file. They just operate on the text of the file, and the preprocessor could be implemented as a separate step that just feeds new text into the actual compiler.
The best way to modify the actions of an include depending on the caller is to use further macros inside the included files, that you can #define before including them.
Still, your overall syntax is off, you can't (typically) nest functions in C.
No, and you should not try to write a program with two functions of the same name.
In the special case that the functions are actually defined in the header file (instead of just prototypes), you can do this:
#define function function_file1
#include "file1.h"
#undef function
#define function function_file2
#include "file2.h"
#undef function
int
main (void)
{
int a = 2;
printf ("%d\n", function_file1 (a));
printf ("%d\n", function_file2 (a));
}
BUT if you rename a function prototype then you haven't actually renamed the real function, so you'll get undefined symbol error when you link.
In any case, if you have two functions defined with the same name then it won't link anyway, not matter what else you do in the sources. (In C++, it is sometimes possible to define two things with the same name, but the One-Definition-Rule means the linker is allowed to assume they are both the same thing really and just pick one.)
This is why libraries are supposed to use names that won't be used elsewhere - usually by adding a common prefix to all symbol names (e.g. my_unique_lib_initialize()).
Why not use array of function pointers. Sure you need to initialize it at the start but I think it probably solves what you want to do.
int process1_function(int var);
int process2_function(int var);
int main(void)
{
int i, a = 10;
int (* functions[2])(int);
functions[0] = process1_function;
functions[1] = process2_function;
for(i=0; i < 2; i++)
{
printf("%d", (functions[i])(a));
}
return 0;
}
If you do not need to dynamically change which function you're going to call you can also just prefix the functions:
int process1_function(int var);
int process2_function(int var);
int main(void)
{
printf("%d",process1_function(a));
printf("%d",process2_function(a));
return 0;
}
Lets say I have a main.c file
#include "library.h"
#define LIBRARY_VALUE 5
int main(void)
{
somefunction1();
return 0;
}
library.h
void somefunction1(void);
library.c
#include "library.h"
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
#endif
static unsigned char oneString[LIBRARY_VALUE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void)
{
printf("The Library Value is %d\n", LIBRARY_VALUE);
}
What I want to do here, is to be able to compile main.c and having LIBRARY_VALUE‘s value to be used as I defined right after the include in main.c.
How should I use GCC in order to achieve this?
I do need the value to be defined in main.c.
In case I have to change my code, I need a minimum working example code please. So I know clearly how to do this. Thanks.
In C there is no way for different .c files to share a common macro defined in one of the .c files. The tradition is to put it in a .h file, but you say this will not work for you.
You will need a type of "constructor" function that sets up your "static" information at run time. This constructor can be called directly by main.c, or indirectly by having main.c define an extern the library picks up.
I'll throw you some code, but I haven't tried to compile it... I'll leave that as an exercise for the student.
main.c
#include "library.h"
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
library.h
extern int const library_value;
void somefunction1(void);
library.c
#include <assert.h>
#include "library.h"
static unsigned char *oneString;
// destroy any memory from lib_init().
static void lib_clear(void)
{
if ( oneString )
{
free(oneString);
oneString = NULL;
}
}
// initialization - strop the static if the caller is to start it up.
static void lib_init( void )
{
if ( ! oneString ) // (defensive "if" to be sure)
{
assert( library_value > 0 );
oneString = (unsigned char*)malloc( library_value );
atexit( &lib_clear );
}
}
void somefunction1(void)
{
if ( ! oneString ) // if the main() is not calling an the constructor then
lib_init(); // // every method within the library must do so.
printf("The Library Value is %d\n", library_value);
}
The lib_init() and lib_clear() methods could be made externs with a lib_init( int size ) signature to take the size.
Your goal seems to have a single definition referenced multiple places.
There are a limited number of possibilities:
#define in .h
extern defined in main, or somewhere else outside of library.
extern defined in library.
Value passed by caller to library, perhaps an initialization call for the library.
Something defined before #include library.h that is picked up by library.h. I don't like this one.
As alfa says, make it a compile-time definition.
An example of a #define within library.h.
// library.h
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
void somefunction1(void);
#endif
Or, have main define a value defined by the caller and referenced by the library:
// library.h
extern int const library_value; // caller to define in main
void somefunction1(void); // function for caller
// main.c
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
The one I don't like is:
//main.c
#define LIBRARY_VALUE 5
#include "library.h"
//library.h
#ifdef LIBRARY_VALUE
int const library_value = LIBRARY_VALUE; // executable code in .h files is evil
#endif
Some of the reasons I dont' like this is that it is obscure and unconventional, if two or more callers of library.h define LIBRARY_VALUE you will, or at least should, get obscure link time errors. The same applies if LIBRARY_VALUE is not defined by an #include... library.c itself can not define a default value. No, I'd much rather call an initialization function for the library that accepts the constant.
The problem with the way you seem to want this to work, is that the constant gets used when the library is compiled -- you can't use one value when compiling the library and then compile a program with a different value and expect the library's code to magically change to use the new constant. You have some options when it comes to alternatives, though.
You could move the array into the program rather than the library, and give the library a pointer to it, and its size.
Or you could use a dynamically allocated array in the library, and add an initialization function to do the allocation (using the size provided by the program).
Or, you could ditch the library and just compile its code as part of the program -- then you can use a constant defined for the program as long as its done where the (previously) library code will see it.
Recommendation (assuming you want "myarray" visible outside the library):
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
extern unsigned char myarray[ARRAY_SIZE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
Otherwise, if you just want "somefunction1()" and the array size, then declare another function, "array_size ()":
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
int array_size (); // library.c will define "myarray" and it will
// define function array_size as "return ARRAY_SIZE;"
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
ALSO:
Please remember that "static" has two meanings:
1) Hides visibility of a variable or function name to file scope (the name is "invisible" outside of the source file)
2) allocates space for the object from static storage (instead of the heap (malloc/new) or stack (local variables)).
If you only want the "static storage" part; then you don't need the keyword "static". Just define your variable outside of a function, and you're set :).
Yet another issue is whether you want to make "ARRAY_SIZE" a compile time variable. If so, you should make sure it gets defined EXACTLY ONCE (when library.c is compiled), and is used IN ONLY ONE PLACE (library.c and library.c only). For example:
// library.c
#include "library.h"
#ifndef ARRAY_SIZE
#error ARRAY_SIZE IS UNDEFINED!
#else
static unsigned char myarray[ARRAY_SIZE];
int array_size ()
{
return ARRAY_SIZE;
}
#endif
...
What you are trying to do is not possible because library.c and main.c are compiled separately. You should compile library.c with "gcc -DLIBRARY_VALUE=5 ..." instead.