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"
}
Related
I want to implement unit testing using the -Wl,--wrap trick, however this doesn't work for functions within the same file. One solution is to rename the function (after it has been defined) to the wrapped one, as suggested here: https://stackoverflow.com/a/11758777/526568
I came up with the following macro to avoid having to manually define __wrap_foo:
#define UNIT_TEST_SYMBOL(x) \
typeof(x) __wrap_##x __attribute__((weak, alias(#x)))
void foo(void) {
/* function body */
}
UNIT_TEST_SYMBOL(foo);
#define foo __wrap_foo
void bar(void) {
foo();
}
I then compile with -Wl,--wrap=foo.
Is it possible to avoid having to manually define foo to __wrap_foo? Can this be somehow part of the UNIT_TEST_SYMBOL?
I'd like to inline some functions, however, they are shared across the team and I don't want to force people to use them.
What would be the best way to add inline versions?
// normal
int func1();
int func2();
// inline versions
inline int inl_func1() { ... }
inline int inl_func2() { ... }
Would something like that make sense?
Edit:
Ideally:
I wouldn't have to write the same function definitions (function body) twice.
It would all be handled with s single define.
Declare/define the inline version and declare the non-inline version in the header file with different names.
// "func.h"
// normal
int func1(void);
int func2(void);
// inline versions
static inline int func1_inline(void) { ... }
static inline int func2_inline(void) { ... }
This allows a user to use either form or both. There is little compelling reason to use the same name and only allow one form.
Both can be handy for code that needs speed vs. space on some calls and not others.
This has a benefit that the one .c file that defines/implements func1(), func2() can use simple code to insure equivalent functionality.
#include "func.h"
int func1(void) {
return func1_inline();
}
int func2(void) {
return func2_inline();
}
BTW, declaring a function like int func1(); does not mean the same as int func1(void);. int func1(); means func1 returns an int, but provids no information about what can be passed to it. It is more like pseudo-code int func1(...);
Perhaps you could tell the people who want the inline functions to define a specific macro before including your header file:
#define WANT_INLINE_FUNC1
#include "awesome_funcs.h"
People who want the to call the externally linked function should omit the macro:
#include "awesome_funcs.h"
Then, in "awesome_funcs.h":
#ifdef WANT_INLINE_FUNC1
inline int func1(int param)
{
/* function body here */
}
#else
extern int func1(int param);
#endif
You also need to define a copy of the function with external linkage in one of your library files, e.g. in "awesome_funcs.c":
#define WANT_INLINE_FUNC1
#include "awesome_funcs.h"
/*
* This will define func1 with external linkage,
* but the function body is copied from the inline definition
* in "awesome_funcs.h".
*/
extern int func1(int param);
EDIT 1
You could combine this with chux's answer and get the best of both worlds (unless that makes things too confusing for your users). Just replace func1 in "awesome_funcs.h" with the following:
static inline int inl_func1(int param)
{
/* function body here */
}
#ifdef WANT_INLINE_FUNC1
inline int func1(int param)
{
return inl_func1(param);
}
#else
extern int func1(int param);
#endif
Then inl_func1 will always be the inline version, and func1 may or may not be inline, depending on whether or not the WANT_INLINE_FUNC1 macro was defined before including "awesome_funcs.h".
What would be the best way to add inline versions?
Your easiest course of action would be to declare static inline versions of these functions:
static inline int func1() { ... }
static inline int func3() { ... }
The function names do not need to differ from those of the corresponding external functions. However, if you #include a header that has declarations of functions with those names, then they must be compatible, AND there must be prior static declarations. For example:
static inline int func1(/* params */);
static inline int func3(/* params */);
#include "our_functions.h"
// ...
static inline int func1(/* params */) {
// implementation ...
}
static inline int func3(/* params */) {
// implementation ...
}
This will allow you to add inline versions without modifying your existing code that calls the external versions of these functions, and without affecting any other translation units. There is at least one alternative, but I don't see anything to recommend it over the above for your particular circumstances.
Can anyone please solve the following problem for me:
Problem: Let say there are two functions foo() and bar() defined as
void bar()
{
printf("bar\n");
}
void foo()
{
printf("foo\n");
bar();
}
So, here I want to change the function name bar to bar_test in its definition but not in calling. This should be runtime and the source code should not be modified.
The expected output is as below:
void bar_test()
{
printf("bar\n");
}
void foo()
{
printf("foo\n");
bar();
}
Thanks
One way would be to have a macro like
#define bar() bar_test()
Now calling bar() by the macro calls bar_test()
The function which is defined should be called as per the standard.
There is no option to change the function name during runtime and it doesn't make sense also.
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();
/* ... */
}
Hey, I'm trying to wrap a function in my program without using LD_PRELOAD.
I have two functions with the same signature:
void someFunc () {
puts ("someFunc");
}
void someFunc_wrapper () {
puts ("someFunc_wrapper");
}
And I want to redirect any function call to someFunc with a call to the wrapper function.
Of course I could do that with defining macros or put the wrapper function into a shared library and then call the program like this:
LD_PRELOAD=./mylib.so my_program
However, I want to redirect the function calls at runtime, without modifying the program call.
As I understand, it should be possible to redirect these calls by modifying the executable's symbol table at runtime.
Any help will be appreciated :)
ld has the option --wrap=symbol that should do what you want. The manual page has an example how it works.
Even if it is doable, modifying your program's symbol table might not be enough in the general case - think about the compiler inlining your function.
You could do this without dirty tricks by using an indirect function call though (always call that function via a pointer-to-function, update that pointer when you want to switch implementations).
Note that this has some runtime overhead (one more indirection). Whether that's important or not depends on the use case. And it can be turned off at compile time with macro tricks if that's just a debug feature you're implementing.
#include <stdio.h>
void foo(void) {
printf("Hello from foo\n");
}
void bar(void) {
printf("Hello from bar\n");
}
#ifdef INTERCEPT
typedef void(*myfunptr)(void);
myfunptr thingy = foo;
void turnonbar(void)
{
thingy = bar;
}
#else
#define turnonbar()
#define thingy foo
#endif
int main(void) {
thingy();
turnonbar();
thingy();
return 0;
}