Lets say I have the following code:
void test(void)
{
#define INIT_DONE
//General initialization stuff
}
void test2(void)
{
#ifndef INIT_DONE
#error "Call function test() first!"
#endif
// Specific initialization stuff
}
And then in main() I call these function as follows:
int main(void)
{
test();
test2();
}
And even though I call test() first, and #define INIT_DONE I still get:
"Call function test() first!"
error on the compiler.
So, how can I achieve, that the function test() has to get called first before any other functions. I could do this with some global boolean variable or something, but I am hoping there is a preprocessor way of doing it. Is there?
The preprocessor runs before your code is handled to the compiler. Everything it does happens before your code runs. The prepocessor has no notion of functions or variables, it just copies input to output and expands macros in between (it actually does some more stuff but that's unimportant). For your code, the preprocessor essentially sees this:
gibberish
#define INIT_DONE
// comment
more gibberish
#ifndef INIT_DONE
#error "Call function test() first!"
#endif
// another comment
even more gibberish
The preprocessor walks through that and first sees #define INIT_DONE, so it defines the macro INIT_DONE to 1; every future appearance of INIT_DONE will be replaced by 1 discarded before the compiler sees the code. Then it sees #ifndef INIT_DONE, but INIT_DONE is already defined so it skips the following bit.
The point is that at no point the preprocessor cares about what is being executed. To do what you want to, use something like this:
#include <assert.h>
/* only visible in the source code form where test() and test2() are defined */
static int init_done = 0;
void test(void)
{
init_done = 1;
/* ... */
}
void test2(void)
{
assert(init_done);
/* ... */
}
There is generally no way to do this in the preprocessor since the preprocessor runs before your program runs. You can also leave these checks out and just emphasize that initialization needs to be done in your documentation. Another approach is to not require initialization by the programmer at all, that is useful depending on the circumstances:
static int init_done = 0;
/* same initialization function as before */
void test(void)
{
init_done = 1;
/* ... */
}
void test2(void)
{
if (!init_done)
test();
/* ... */
}
Related
I would like to make function to be callable (e.g. exposed) to the rest of the library through the macro only, to prevent accidental undesired side effects.
Why? This is because I have a variadic function, which could be called from another variadic function and that way I would like to add NULL sentinel to the call, using macro, thus making access to va_list much easier and prevent undefined behaviour. There are also other handy scenarios, where this could really be helplful.
An example :
test.h
void _func(char *dummy, ...);
//I would like to make sure that rest of the library
//only calls _func through this macro
#define func(dummy, ...) _func(dummy, __VA_ARGS__, NULL)
test.c
//Implementation of the _func function
static void _func(char *dummy, ...) {
//body goes here...
}
main.c
int main(int argc, char *argv[]) {
//This should not be allowed by compiler
_func("dummy", "arg1");
//This should be allowed by compiler, but since definition
//of _func is static in test.c file, compiler is not happy anyway
//LNK2001 unresolved external symbol __func
func("dummy", "arg1");
return 0;
}
I've already tried with #define and #undef compiler directives to somehow force this scenario, but no avail. Is this even possible in C?
You can shadow the function with a macro:
void _func(char *dummy, ...);
#define _func(...) error_use_the_macro_func_instead_of_calling__func_directly
// Always use the macro "func" instead of calling "_func" directly.
#define func(dummy, ...) (_func)(dummy, __VA_ARGS__, NULL)
Notice the parentheses around _func in the macro. This prevents the _func from being recognized as a function-like macro and gives the macro access to the function. If somebody tries to call _func directly, they get
error C2065: 'error_use_the_macro_func_instead_of_calling__func_directly': undeclared identifier
This "macro shadowing" technique has the advantage of being usable in expression contexts:
for (int i = 0; i < 5; func("incrementing i", ++i)) { ... }
or if we change the situation slightly and give _func a return value:
int _func(char *dummy, ...);
#define _func(...) error_use_the_macro_func_instead_of_calling__func_directly
// Always use the macro "func" instead of calling "_func" directly.
#define func(dummy, ...) (_func)(dummy, __VA_ARGS__, NULL)
then this allows you to do things like
int i = func("hello", 2) * func("there", 3);
Maybe you can scope the visibility of the private function? Here's a snippet to illustrate what I mean. Not pretty, but it may work for you(no MSVC to test with here)
#define func(a, b) do { \
extern void private_func(int , int );\
private_func(a, b);\
} while (0)
void foo(void)
{
func(1, 2);
private_func(3, 4);
}
What #Bjorn A. has written in the post above, actually solves my problem as compiler gets angry with the message : '_func': redefinition; different basic types if I try to call _func directly.
Here is the adopted example :
test.h
#define func(dummy, ...) do { \
extern void _func(char *, ...);\
_func(dummy, __VA_ARGS__, NULL);\
} while (0)
test.c
//Implementation of the _func function
//static has to be omitted here, but it doesn't matter
void _func(char *dummy, ...) {
//body goes here...
}
main.c
int main(int argc, char *argv[]) {
//'_func': redefinition; different basic types
//if we try to call _func directly
_func("dummy", "arg1");
//this is ok
func("dummy", "arg1");
func("dummy2", "arg2");
return 0;
}
EDIT : Actually, #Raymond Chen has proposed much better solution with function shadowing - idea is to enclose the function name with parentheses to stop preprocessor from expanding it. More info about that here.
Here is the final (hopefully) solution that works like a charm :
test.h
void _func(char *dummy, ...);
#define _func(...) error_use_the_macro_func_instead_of_calling__func_directly
#define func(dummy, ...) (_func)(dummy, __VA_ARGS__, NULL)
test.c
//Notice the _func is enclosed with parentheses here
void (_func)(char *dummy, ...) {
//body goes here...
}
main.c
int main(int argc, char *argv[]) {
//C2065 'error_use_the_macro_func_instead_of_calling__func_directly': undeclared identifier
//if we try to call _func directly
_func("dummy", "arg1");
//this is ok
func("dummy", "arg1");
func("dummy2", "arg2");
return 0;
}
Many thanks! Cheers!
In this example code a macro is either defined or commented out by the programmer in order to remove a function from the released software.
#include <stdio.h>
#define MACRO //or omitted
#ifdef MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#else
#define Function(str)
#endif
int main(void)
{
Function("hello world");
getchar();
return 0;
}
Is there anything wrong with this?
Even though your solution works, I prefer the following approach:
#include <stdio.h>
#define MACRO //or omitted
#ifdef MACRO
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif
#ifdef MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#endif
int main(void)
{
FUNCTION("hello world")
getchar();
return 0;
}
Note: FUNCTION is the macro, Function is the actual name of the function
This works by defining the macro FUNCTION(a) to a call to Function(const char*) when MACRO is enabled. On the other hand, when MACRO is disabled, calls to FUNCTION(a) will be defined to nothing.
I tend to prefer this method since it would be easier to abstract away the macro used to define your call from the macro defining your function definition. You might have cases where in release mode you only need to remove some of the calls to Function. In that case the definition of Function() is still required. For example:
#include <stdio.h>
#define DEBUG //or omitted
#ifdef DEBUG
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif
void Function(const char* str)
{
printf("%s\n", str);
}
int main(void)
{
// Call function with Hello World only in debug
FUNCTION("hello world")
getchar();
// Call function with goodbye world in both debug and release
Function("goodbye world");
return 0;
}
It will work. But the entire symbol is removed this way. I prefer the following method.
#include <stdio.h>
#define MACRO 1
#if MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#else
void Function(const char *str){}
#endif
int main(void)
{
Function("hello world");
getchar();
return 0;
}
The following has changed:
The #if now compares a boolean. Your IDE is now able to find where MACRO is defined, in all cases. (right click, find definition)
You can, by changing MACRO to 2, change the entire meaning of Function. For example, a release compiled variant might contain a print to file or system log.
There will always be a symbol for Function, even if it does nothing, even in compiled code. This has the benefit that the string literals in the argument still count to the size statistics. As an embedded developer, I find this important.
Obviously, this is partly the preference of the one who crafts the code.
Let's say I have a function macro in C called FOO. There are also two macros called BAR1 and BAR2, which are basically two flavors of the same macro. I'd like to write a macro BAR such that it expands to BAR1 in functions which invoke FOO somewhere before the use of BAR and to BAR2 otherwise. So for example:
void func1(void)
{
FOO();
...
BAR();
}
would be equivalent to
void func1(void)
{
FOO();
...
BAR1();
}
while this function:
void func2(void)
{
BAR();
}
would be equivalent to
void func2(void)
{
BAR2();
}
I'd like to avoid introducing global variables or doing additional checks at runtime. Is this even possible?
Short answer: NO. The C precompiler knows nothing about function limits, so even if you managed to modify the BAR macro as you want it, that would not be limited to the current function anyway.
Now, if you are willing, you can add some checks to the BAR macro. And those checks can be written to be resolved at compile time, so no runtime overhead results.
For example:
extern char _sentinel_[2];
#define FOO() char _sentinel_;
#define BAR() if (sizeof(_sentinel_) == 1) BAR1() else BAR2()
The trick is that the look up of variable _sentinel_ will resolve the global variable or the local one, depending on the use of FOO(). And since the condition in the if is a compiler constant, the compiler will optimize out the other branch.
My attempted hack at using gotos failed because when FOO() isn't used, the jump label is missing for BAR(). But, fear not, I've come up with an even more gross hack.
You can use #includes instead of a macro for FOO() and BAR(). This will allow you absolute control on how the code gets expanded.
/* FOO file */
#define BAR_IS_BAR2
/* whatever code FOO needs to do */
/* BAR file */
#ifdef BAR_IS_BAR2
BAR2();
#undef BAR_IS_BAR2
#else
BAR1();
#endif
/*...in you source code...*/
void func1 () {
#include "FOO"
/*...*/
#include "BAR"
}
void func2 () {
#include "BAR"
}
In the C language, __FUNCTION__ can be used to get the current function's name.
But if I define a function named a() and it is called in b(), like below:
b()
{
a();
}
Now, in the source code, there are lots of functions like b() that call a(), e.g. c(), d(), e()...
Is it possible, within a(), to add some code to detect the name of the function that called a()?
Further:
Sorry for the misleading typo. I have corrected it.
I am trying to find out which function calls a() for debugging purposes. I
don't know how you do when in the same situation?
And my code is under vxWorks, but I am not sure whether it is related to C99 or
something else.
There's nothing you can do only in a.
However, with a simple standard macro trick, you can achieve what you want, IIUC showing the name of the caller.
void a()
{
/* Your code */
}
void a_special( char const * caller_name )
{
printf( "a was called from %s", caller_name );
a();
}
#define a() a_special(__func__)
void b()
{
a();
}
You can do it with a gcc builtin.
void * __builtin_return_address(int level)
The following way should print the immediate caller of a function a().
Example:
a() {
printf ("Caller name: %pS\n", __builtin_return_address(0));
}
If you are using Linux system, you can use the backtrace() function.
See the man page for more details and a code example.
Try this:
void a(<all param declarations to a()>);
#ifdef DEBUG
# define a(<all params to a()>) a_debug(<all params a()>, __FUNCTION__)
void a_debug(<all params to a()>, const char * calledby);
#endif
void b(void)
{
a(<all values to a()>);
}
#ifdef DEBUG
# undef a
#endif
void a(<all param declarations to a()>)
{
printf("'%s' called\n", __FUNCTION__);
}
#ifdef DEBUG
void a_debug(<all param declarations to a()>, const char * calledby)
{
printf("'%s' calledby '%s'", __FUNCTION__, calledby);
a(<all params to a()>);
}
#endif
If for example <all param declarations to a()> is int i, double d, void * p then <all params to a()> is i, d, p.
Or (less evil ;->> - but more code modding, as each call to a() needs to be touched):
void a((<all params of normal a()>
#ifdef DEBUG
, const char * calledby
#endif
);
void a((<all params of normal a()>
#ifdef DEBUG
, const char * calledby
#endif
)
{
#ifdef DEBUG
printf("'%s' calledby '%s', __FUNCTION__, calledby);
#endif
...
}
...
void b(void)
{
a(<all params of normal a()>
#ifdef DEBUG
, __FUNC__
#endif
);
}
__FUNCTION__ is available on GCC (at least?), if using a different C99 compiler replace it with __func__.
Refer: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
A backtrace is a list of the function calls that are currently active
in a thread. The usual way to inspect a backtrace of a program is to
use an external debugger such as gdb. However, sometimes it is useful
to obtain a backtrace programmatically from within a program, e.g.,
for the purposes of logging or diagnostics.
The header file execinfo.h declares three functions that obtain and
manipulate backtraces of the current thread.
If you're only after knowing where you were for logging/debug purposes you can use a macro to avoid __func__ giving the name of your logging/debug function but of the function calling it.
Being in a macro will not result in a change to __func__ but will "feel" like using a function.
e.g.
#define LOG(s, data...) log("%s: "s, __function__, ## data)
If your platform is Windows, you may use this: walking the callstack
You can tag each function that calls a() with an integer identifier which is passed to a() as a parameter and then use a switch-case construct in a() to tell which function has invoked a().A printf() would tell which function invoked a() depending on the integer identifier value if you use that as an argument to a switch-case construct in a()
#include<stdio.h>
void a(int);
void b();
void c();
void d();
int main(void)
{
b();
c();
d();
}
void b()
{
int x=1;
a(x);
}
void c()
{
int x=2;
a(x);
}
void d()
{
int x=3;
a(x);
}
void a(int x)
{
switch(x)
{
case 1:
printf("b called me\n");
break;
case 2:
printf("c called me\n");
break;
case 3:
printf("d called me\n");
}
}
If the function in question is in a different c file, you can do
#define name_of_function(...) \
printf("Function %s is parent\n", __FUNCTION__); \
name_of_function(__VA_ARGS__);
And at the top of the c file it lives in
#ifdef name_of_function
#undef name_of_function
#endif
If they're in the same file, you can wrap the function definition in the second macro, then redefine the first macro at the end.
It's not terribly extensible because you can't generate new defines from other defines, but if you're trying to track down parents for a particular function it works without any nonsense.
https://godbolt.org/z/f2jKOm
#include <stdio.h>
#include <stdlib.h>
#define FUNCTION_NAME(FUNCTION) printf("FUNCTION=%s \r\n", #FUNCTION);
int a() {
printf("A function call");
}
int b() {
printf("B function call");
}
int main(){
FUNCTION_NAME(a);
FUNCTION_NAME(b);
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.