Wrapping a normal C function call in another static inline function? - c

I have seen code like the simplified example below:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int myfunc(int a) {
return a + rand();
}
static inline int myfunc_stat(void) {
return myfunc(0);
}
int main(void) {
srand(time(NULL));
int intern = myfunc(0); //myfunc_stat();
printf("intern is %d\n", intern);
return 0;
}
... that is: there is a "normal" function myfunc that accepts a an argument; and then there is a static inline function myfunc_stat which does not receive arguments, and returns the return of the "normal" function called with the constant argument.
I was wondering - would there be any special benefits in "wrapping" a "normal" function in a "static inline" function as shown? At this time, I simply cannot see any difference - in principle, the way I see it, the compiler should just inline the call to myfunc_stat from main, and then there would be a "normal" call to myfunc from there.
But it seems, this example is so simple, I get exactly the same assembly, regardless of if I call myfunc(0); or myfunc_stat(); in main(), from https://godbolt.org/z/M67PTnqeT - the compiler basically decides to inline both functions in either case.
But if the myfunc function was not so obviosly simple (or the build was not optimized), would there be some difference/side-effect/benefit to using a call to myfunc_stat(); as opposed to myfunc(0); (aside from the purely semantic?)

If fifty calls to foo() within a program pass a constant value of zero, having them all call a non-inline function foo_zero which accepts no arguments, and which passes zero to foo will require generating code for foo_zero, but the generated code for each foo_zero(); would likely be an instruction smaller than the code for each foo(0);. On an ARM Cortex-M3, the code for foo_zero() would likely be six bytes, each call foo_zero(0) would take six bytes, and foo_zero() would take four. If foo(0) would get called fifty times, that would likely save 94 bytes of code.
If, however, foo_zero() only got called twice, then the six bytes required for the generated code of foo_zero() would exceed the four bytes saved at other call sites, rendering this attempted optimization counter-productive.
If one is using a compiler that in-line expands functions which are declared static inline, but not others, then one could control whether machine code called foo(0) directly or created and used a foo_zero() wrapper. Since the choice of which is optimal would depend on how much the function is used throughout a program, a compiler that examines source files in isolation would have no way to make that decision optimally.

Related

Declare global variable after function

Why do we need to declare global variables before function defining and declaring since we call this function after this variable declaration? Isn't it that compiler read line by line? I mean while calling the function compiler should know what's x.
void function()
{
x += 3
}
int x = 3;
int main(void)
{
function();
return 0;
}
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
You can think at the job of the compiler like this; it reads the source file token by token (not exactly line by line) and when sufficient tokens are read, it outputs the translation. It repeats that, until the source file is (correctly) finished: the job of the compiler is done.
For every token the compiler reads, it needs to know what the token represents. If it doesn't know, an error is generated.
So, while compiling your function
void function()
{
x += 3
}
it encounters an "x" but does not know what it represents (an integer? A float? Something else?). -error-.
Why do we need to declare global variables before function defining and declaring
Declaration and Definition are two different things. The compiler needs a declaration in order to know how to manage an identifier; the real definition can be somewhere else, even in another source (or already compiled) file.
And one more question. I know that we can define function after main function provided we declared this function before main. Then how does main function see these functions after main function? Does the compiler first read the whole file and then run main() or sth?
As explained before, all the compiler needs is a declaration, so it can output correct (object) code. If you declare function(), then define main(), then define function(), the compiler has enough to generate correct output, which will consist of code for main() and code for function() (we can say "in this order"). The next step, the linker, will take care to connect these two functions.
The definition of function() could also be absent: the compiler still would generate correct code for main(); the linker would instead complain, unless you tell it where to find the definition/implementation of function().
Also note that a definition is also a declaration. So if in your source you declare function() and then main(), you don't need forward declaration.
In the comments I've read that perhaps you are confusing interpreters with compilers - this is true, if you try to compare Python with C: very different beasts. A big difference is compiler vs interpreter, the compiler generates data (object code) but does not link it (and neither runs it). An interpreter instead is a compiler+linker+runtime, all packed together. Normally a compiler generates code that is much faster than the equivalent interpreted program, but to do this it needs accurate informations (precise types and declarations) and often (always?) is less versatile. The interpreter is often more versatile but it can not exploit all the optimizazions a good compiler can do.
Why do we need to declare global variables before function defining
and declaring since we call this variablefunction after this
declaration?
The c language is a strictly typed language. When the compiler processes an identifier it needs to determine its type to generate correct object code.
It is not necessary that a global variable used in a function shall be declared exactly before the function definition. But in any case it shall be declared before its usage in a function.
Here is a demonstrative program.
#include <stdio.h>
void function( void )
{
extern int x;
x += 3;
}
int x = 3;
int main( void )
{
function();
printf( "x = %d\n", x );
}
The program output is
x = 6
Here the variable x declared within the function refers to the global variable x defined after the function.
Then how does main function see these functions after main function?
Does the compiler first read the whole file and then run main() or
sth?
C is a compilation language. It does not run programs. It generates object code that then after some processing by the linker can be run.
In the point where a function is used what the compiler is need is the type of the function that to check whether the function is used correctly. If the function is an inline function then it can substitute its call for the function body It can rebuild the object code when the inline definition in the translation unit will be known.

Direct access to the function stack

I previously asked a question about C functions which take an unspecified number of parameters e.g. void foo() { /* code here */ } and which can be called with an unspecified number of arguments of unspecified type.
When I asked whether it is possible for a function like void foo() { /* code here */ } to get the parameters with which it was called e.g. foo(42, "random") somebody said that:
The only you can do is to use the calling conventions and knowledge of the architecture you are running at and get parameters directly from the stack. source
My question is:
If I have this function
void foo()
{
// get the parameters here
};
And I call it: foo("dummy1", "dummy2") is it possible to get the 2 parameters inside the foo function directly from the stack?
If yes, how? Is it possible to have access to the full stack? For example if I call a function recursively, is it possible to have access to each function state somehow?
If not, what's the point with the functions with unspecified number of parameters? Is this a bug in the C programming language? In which cases would anyone want foo("dummy1", "dummy2") to compile and run fine for a function which header is void foo()?
Lots of 'if's:
You stick to one version of a compiler.
One set of compiler options.
Somehow manage to convince your compiler to never pass arguments in registers.
Convince your compiler not to treat two calls f(5, "foo") and f(&i, 3.14) with different arguments to the same function as error. (This used to be a feature of, for example, the early DeSmet C compilers).
Then the activation record of a function is predictable (ie you look at the generated assembly and assume it will always be the same): the return address will be there somewhere and the saved bp (base pointer, if your architecture has one), and the sequence of the arguments will be the same. So how would you know what actual parameters were passed? You will have to encode them (their size, offset), presumably in the first argument, sort of what printf does.
Recursion (ie being in a recursive call makes no difference) each instance has its activation record (did I say you have to convince your compiler never optimise tail calls?), but in C, unlike in Pascal, you don't have a link backwards to the caller's activation record (ie local variables) since there are no nested function declarations. Getting access to the full stack ie all the activation records before the current instance is pretty tedious, error prone and mostly interest to writers of malicious code who would like to manipulate the return address.
So that's a lot of hassle and assumptions for essentially nothing.
Yes you can access passed parameters directly via stack. But no, you can't use old-style function definition to create function with variable number and type of parameters. Following code shows how to access a param via stack pointer. It is totally platform dependent , so i have no clue if it going to work on your machine or not, but you can get the idea
long foo();
int main(void)
{
printf( "%lu",foo(7));
}
long foo(x)
long x;
{
register void* sp asm("rsp");
printf("rsp = %p rsp_ value = %lx\n",sp+8, *((long*)(sp + 8)));
return *((long*)(sp + 8)) + 12;
}
get stack head pointer (rsp register on my machine)
add the offset of passed parameter to rsp => you get pointer to long x on stack
dereference the pointer, add 12 (do whatever you need) and return the value.
The offset is the issue since it depends on compiler, OS, and who knows on what else.
For this example i simple checked checked it in debugger, but if it really important for you i think you can come with some "general" for your machine solution.
If you declare void foo(), then you will get a compilation error for foo("dummy1", "dummy2").
You can declare a function that takes an unspecified number of arguments as follows (for example):
int func(char x,...);
As you can see, at least one argument must be specified. This is so that inside the function, you will be able to access all the arguments that follow the last specified argument.
Suppose you have the following call:
short y = 1000;
int sum = func(1,y,5000,"abc");
Here is how you can implement func and access each of the unspecified arguments:
int func(char x,...)
{
short y = (short)((int*)&x+1)[0]; // y = 1000
int z = (int )((int*)&x+2)[0]; // z = 5000
char* s = (char*)((int*)&x+3)[0]; // s[0...2] = "abc"
return x+y+z+s[0]; // 1+1000+5000+'a' = 6098
}
The problem here, as you can see, is that the type of each argument and the total number of arguments are unknown. So any call to func with an "inappropriate" list of arguments, may (and probably will) result in a runtime exception.
Hence, typically, the first argument is a string (const char*) which indicates the type of each of the following arguments, as well as the total number of arguments. In addition, there are standard macros for extracting the unspecified arguments - va_start and va_end.
For example, here is how you can implement a function similar in behavior to printf:
void log_printf(const char* data,...)
{
static char str[256] = {0};
va_list args;
va_start(args,data);
vsnprintf(str,sizeof(str),data,args);
va_end(args);
fprintf(global_fp,str);
printf(str);
}
P.S.: the example above is not thread-safe, and is only given here as an example...

Multiple definition of main()

Hi guys trying to use two main() and getting this error multiple definition of main(). I renamed my main functions then why is this error and also first defined here for my print().
header file:
#ifndef TOP_H_
#define TOP_H_
#include <stdio.h>
#include <string.h>
#define onemain main
#define twomain main
inline void print();
#endif /* TOP_H_ */
c file one:
#include "top.h"
void print();
int onemain()
{
print();
return 0;
}
void print()
{
printf("hello one");
}
c file two:
#include "top.h"
void print();
int twomain()
{
print();
return 0;
}
void print()
{
printf("hello two");
}
Basically any C (or even C++) program is a bunch of functions calling each other.
To begin a program execution, you have to pick one of these functions and call it first.
By convention, this initial function is called main.
When you include several source files in a project, the IDE compiles them all, then calls the linker which looks for one single function called main and generates an executable file that will call it.
If, for any reason, you defined two "main" functions inside all these files, the linker will warn you that it cannot choose on its own which one you intended to be the starting point of your program.
The macro substitution of onemain and twomain occurs before the compiler proper sees the program, so that doesn't make a difference. The functions are both named main.
C++ allows different functions with the same name, but does not allow two definitions of the exact same function signature. There would be no way to form a function call expression that would reach either overload. Additionally, the functions are the same entity, and one thing cannot have two definitions.
In addition, in C++ main cannot be overloaded, because the program is supposed to start when the unique main function is called, and any given system detects what format of main the particular program uses, out of a variety of allowed formats. (This auto-detection feature also applies to C.)
But you are not asking about C++; in C, without function overloading, there are no redefinitions of the same name, even for different signatures. Each name of extern linkage in C uniquely identifies an entity, so you cannot have two.
It's unclear what you want the resulting program to do. Most likely you need to build two separate programs.
I don't get what you ask - your error messages are quite clear:
You have 2 definitions of print(), which will collide. Remove one.
You as well have 2 definitions of main() - your #defines will replace your onemain and twomain functions, naming them effectively as main.
You overrode the built in print, about main, try imagining a car with two steering wheels ... it wont work ...
Your C program has two have a least one main, so the computer knows where the program starts.
If you have 2 files with two main function, then you have two different programs.
It's not possible for a C program to have more than one main() in it. Also, main() should be declared as an int and return an integer value (usually 0).

Changing stdout (putch() function) on the fly in C

I'm using the XC8 compiler. For that, you have to define your own void putch(char data) function in order for functions like printf() to work, as is described here. Basically, putch() is the function which is used to write characters to stdout.
I now want to change this function on the fly. I have two different functions, putch_a() and putch_b() and want to be able to change which one is used for putch() itself, on the fly.
I thought of this:
unsigned use_a_not_b;
void putch(char data) {
if (use_a_not_b) {
putch_a(data);
} else {
putch_b(data);
}
}
However, this reduces execution speed. Would there be a way to use pointers for this? I have read this answer, and made the following code:
void putch_a(char data);
void putch_b(char data);
void (*putch)(char) = putch_a; // to switch to putch_a
void (*putch)(char) = putch_b; // to switch to putch_b
Would that work? Is there a faster or better-practice way?
No, and why not
To answer your question: no you can't, in the way that you are thinking (i.e. function pointer). What a function pointer is is a variable with an address of another variable. To illustrate, consider how this works when you have a function pointer foo pointing to function bar.
int bar() {
}
void baz(int (*foo)()) {
int x = foo(); // Calls the function pointed to bar foo
}
int main() {
int (*foo)();
foo = &bar;
baz(foo); // Cal baz() passing it foo, which points to bar()
}
What foo holds is the address of bar. When you pass foo to some function that expects a function pointer parameter (in this case baz()), the function dereferences the pointer, i.e. looks at the memory address associated with foo, gets the address sored in it, in our case the the address of bar, and then calls a function (in our case, bar) at that address. To be very careful about this: in the above example baz() says
Let me look at the memory associated with foo, it has another address in it
Load that address from memory, and call a function at that address. That function returns an int and takes no parameters.
Let's contrast this with a function that calls bar() directly:
void qux() {
int x = bar(); // Call bar()
}
In this case there is no function pointer. What there is, is an address, supplied by the linker. The linker lays out all the functions in your program, and it knows, for instance that bar() is at address 0xDEADBEEF. So in qux() there is just a jump 0xDEADBEEF call. In contrast in baz() there is something like (pseudo-addembly):
pop bar off the stack into register A
read memory address pointed to by register A into register B
jump to memory location pointed to by register B
The way putch() gets called from printf(), for instance, is exactly like qux() calls bar(), and not like the way baz() does: putch gets statically linked into your program, so the address of putch() is hardcoded in there, simple because fprintf() doesn't take a function pointer to call for a parameter.
Why #define is not the answer
#define is a preprocessor directive, that is, "symbols" defined with #define are replaced with their values before the compiler even sees your code. This means that #define makes your program less dynamically modifiable not more. This is desirable in some cases, but in your case it will not help you. To illustrate if you define a symbol like this:
#define Pi 3.14
Then everywhere you use Pi it is as if you typed 3.14. Bacause Pi does not exist, as far as the compiler is concerned, you cannot even take an address of it to make a pointer to it.
Closest you can get to a dynamic putch
Like the others have said, you can have some sort of case statement, conditional, or a global pointer, but the putch function itself has to be there in the same form.
Global function pointer solution:
void (*myPutch)(char);
putch(char ch) {
myPutch(ch);
}
int main() {
myPutch = putch_Type_A();
...
myPutch = putch_Type_B();
}
If/then/else solution has been provided in other answers
goto solution: This would be an ugly (but fun!) hack, and only possible on von Neumann-type machines, but in these conditions you could have your putch look like this:
putch(char ch) {
goto PutchTypeB
PutchTypeA:
// Code goes here
return;
PutchTypeB:
// Code goes here
return;
}
You would then overwrite the goto instruction with goto to some other memory address. You'd have to figure out the opcodes for doing this (from disassembly, probably), and this isn't possible on Harvard architecture machines, so it is out on AVR processors, but it would be fun, if cludgey.
No. That isn't guaranteed to work due to the way code is generated and linked. However...
void (*output_function)(char) = putch_a;
void putch(char c) {
output_function(c);
}
Now you can change output_function whenever you like...
There is no concept of "speed" in C. That's an attribute introduced by implementations. There are fast implementations (or rather, implementations that produce fast code, in the case of "compilers") and slow implementations (or implementations that produce slow code).
Either way, this is unlikely to be a significant bottleneck. Produce a program that solves a useful program, profile it to determine the most significant bottlenecks and work on optimising those.
Before you optimize this, make sure what you have really does reduce execution speed noticeably. In an i/o function there's usually a lot of other stuff going on (checking if buffer space is free, calculating buffer offsets, informing hardware data is available, being interrupted while data is actually transmitted to hardware, etc.) that would make a single extra if/else inconsequential.
In most cases your first block should be fine.
In comments you mention maybe needing to extend this structure to multiple putch() functions.
Maybe try
enum PUTCH { sel_putch_a, sel_putch_b, ... };
enum PUTCH putch_select;
void putch(char c) {
switch(putch_select) {
case sel_putch_a : putch_a(c); break;
case sel_putch_b : putch_b(c); break;
/* ... */
}
}
The compiler should be able to optimize the switch statement to a simple computation and a goto. If the putch_<n> functions are inlineable, this doesn't even cost an extra call/return.
The solution using a pointer-to-function in another answer is more flexible in terms of being able to change the available putch functions on the fly, or define them in other files (for example, if you're writing a library or framework to be used by others), but it does require an extra call/return overhead (compared to the simple case of just defining a single putch function).

Putting variable declarations in a separate function in C

Is it possible to put the variable declarations in an external function? After reading from Wikipedia that:
an inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined.
I hypothesized that the following might work. It did not take long for the compiler to slap my fingers :(
inline void declaration(){
int a;
}
int main(){
declaration();
a=2;
return 0;
}
This may not be how it is done but if you want a basic idea of how you can think about what happens when you inline a function.
Imagine the compiler turning your code into something like this, then you see why it will not work.
int main(){
{
int a;
}
a=2;
return 0;
}
The call to declaration() is replaced by the contents of the function including brackets, thus int a; is declared in an inner scope and is not visible in the main function.
No, this is not possible.
What is possible, is to use a preprocessor directive #define:
#define VARBLOCK int a, b, c; char ca, cb, cc;
int main()
{
VARBLOCK;
a = 2;
}
This would be a bad practice. Also these would still be variables only available in the scope of function where it were placed, without values being shared.
No - as far as I'm aware an inline function must behave semantically equivalent to a non-inline function; it doesn't affect what counts as legal code. It's just an optimization.
In particular, you could have a variable called a in both functions, but they'd be separate variables on the stack.
(Even if you could do this, I'd suggest it would be a very bad idea in terms of readability.)
inline functions are usually just a function containing no more than about 4 lines and you would want the compiler to do the optimization you where talking about since it would be faster to do what the function does, rather than adding extra code.
Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently.
So there's nothing special with the inline function, rather than it might be handled differently by the compiler. They don't share their stack with any other function, which would be the only way for main to use a variable that is created in a different scope.
So my tip is; write your functions, and treat them as you usally should. Then when you are done, inline the short ones that you use a lot.
And if you really wanna create a variable in another function, allocate it on the heap in the function and return a pointer that you save and then set to 2 (your case). :) Just remember to free the memory!
You can do this, though:
#include <stdio.h>
int* GetMyIntAddress(void)
{
static int blah = 0;
return &blah;
}
int main(void)
{
printf("%d\n", *GetMyIntAddress());
*GetMyIntAddress() = 123;
printf("%d\n", *GetMyIntAddress());
return 0;
}
blah will be a global variable defined in the scope of the GetMyIntAddress() function.
If you add inline to the definition of GetMyIntAddress(), you are risking to get multiple independent instances of blah if the inline function is used in different modules (e.g. included from a shared header file).

Resources