How to perform conditional function calling in C? - c

So I am doing some work in C where I have implementation of the same function in both assembly and C and I want to compare the performance of C vs assembly implementation. Now for that I would want to be able to compile and call the function conditionally i.e I would want to create a function which would act as an interface between the caller and the right function that I want to call. somehow I am not sure how to do that.
I was thinking somewhere along the line of following:
//header file containing the C definition and the assembly definition
void getstate(state* m, int* values);
extern void kalmanstate(state* m, int* values);
Then the caller can include the above header file and pass either &getstate or &kalmanstate.
void callTheRightFunction(state* m, int* values, void *fnptr(state*,int*))
{
*fnptr(m,values);
}
However the problem with this is that both getstate and kalmanstate will be compiled which kind of defeats the purpose of my simulation. It does not sound to me the best implementation of the wrapper I want to have. I know conditional execution exists in C but how would I use it to get the right function compile? I mean if I do something like this in the header file:
#ifdef __C__FUNC
void getstate(state* m, int *values);
#endif
#ifdef __kalman
void kalmanstate(state *m, int *values)
#endif
Then in the caller:
include "headerfile.h" //include the above header file
//caller defining _C_FUNC
define __C_FUNC
callTheRightFunction(m,p,&getstate);
But since I include the header file at the beginning when none of them are defined it would probably not include any of them at all and thus will generate runtime errro.
Any suggestions towards right direction would be appreciated. Thanks in advance guys!

Based on your addition to the original question, you were wondering if none of the functions would be compiled. Then you'll have to define __C__FUNC or __kalman before you include the header file:
#define __C__FUNC
#include "header.h"
But to avoid this problem when you don't define anything, an approach would be for you to use just one definition, like this, on the SOURCE file:
#ifdef __GSTATE_USE_C_FUNCTION
void getstate(state* m, int *values)
{
// C version
}
#else
void getstate(state *m, int *values)
{
// Assembly version
}
#endif
And on the header file:
void getstate(state *m, int *values);
(Note the same function name, so you don't need to modify the code when you're calling the function)
But this would only work if you're including the header on the source file where getstate is being implemented too. (*1)
Then if you forgot to define __GSTATE_USE_C_FUNCTION before your header inclusion, the second function would be used, because it triggered the #else.
Now, you'd use it like this on a header file that BOTH source files include (that is, the file that implements the function, and the file that uses it):
// Comment the line below if you want the other version
#define __GSTATE_USE_C_FUNCTION
Of course you'd have to include this header before including the header which contains the prototype declaration.
And on the source file:
// Somewhere else on the code where you use the function
getstate(m, values);
So you'd only have to change the #define line on the global header.
In addition, if your compiler has an option to do preprocessor defining in the command line for it, then you'd not even need to define __GSTATE_USE_C_FUNCTION before the #include, you'd just use as a command line option, something like this (for example in bcc32):
bcc32 /D"__GSTATE_USE_C_FUNCTION" hello.c
This would avoid the problem (*1), and you'd not have to make a global header file that both source files have to include.

I see no problem here.
Options:
name the ASM and C functions that do the same differently. Use if or switch or, god forbid, ?: to call the right one.
Same name setup as above. Use a function pointer. If you assign it the address of the ASM function, then function calls through this pointer will go there. If you assign it the address of the C function, the calls will similarly go to the C function.
Same name setup as above. Define a macro that would expand to either the ASM or the C function's name. You can define the macro at compile time using the compiler's options. Use that macro in the code that needs to call one of the two functions.
Place the ASM and C functions into separate .asm/.s and .c files. When compiling either include one file in the list of compiled files or include the other.

Related

Mechanism for including header files in C main body

For a large software developed by C, we first declare all the self-defined functions in a separate header file (e.g. myfun.h). After that, once we write a code (e.g. main.c) that uses the functions listed in myfun.h, we have to #include "myfun.h". I'm wondering how it works, because even if I include the function names declared in header file before the main body, the code cannot see the function details in main.c. I guess it will search the library to get the function details...Am I right?
When you say "it will search the library for the function details" you're not far off, but that isn't quite right. A function declaration, i.e.. a function prototype only contains enough information for the compiler to do two things:
First, the compiler will register the function as a known identifier so that it knows what you're taking about when you call it, as opposed to a random string of letters with parentheses (to the compiler, they are essentially the same thing without a function prototype for either - an error).
Second, the compiler uses the function prototype for checking code correctness. Correctness in this sense means that a function call will match the prototype in both arity and type. In other words a function call to int square(int a, int b); will have two arguments, both integers.
The program doesn't "search the library," though. Function names without parentheses are not function calls but rather function's address. Therefore, when you call a function, the processor jumps to the memory location of the function. (This assumes the function has not been inlined.)
Where is this function located though? It depends. If you wrote the function in the same module, i.e... a .c file that got compiled into an object linked with the main.c file into a single executable, then the location of the function will be somewhere in the .TEXT section of the executable. In other words, it's just a slight offset from the main function's entry point. In a huge project this offset won't be so slight, but it will be shorter than the offset of separate objects.
Having said that, if you compiled this hypothetical function into a DLL which you call from your main program, then the function's address will be determined in one of two ways:
Either you will have generated a .lib/.a? (depending on whether you're on Windows or Linux) file containing the function declaration's and addresses, or:
You will use run-time linking where the main program will calculate the function addresses when it loads the .dll/.so into its address space. First, it will determine where to load it. You can set DLL's to have preferred offsets to optimize load time. Otherwise, libraries will start loading from the first segment available and any additional libraries will need their function address recalculated using this new address, hampering initial load times. Once they are loaded into the program's memory though, there shouldn't be any performance hits thereafter.
Going back to the preprocessor, it's important to note two things. First, it runs before any compilation takes place. This is important. Since the program is not really being "compiled" when the preprocessor is doing its thing, macros are not type-safe. (Insert Haskell joke about C "type safety") This is why you don't -or shouldn't- see macros in C++. Anything that can be accomplished with macros in C can be accomplished by const and inline functions in C++, with the added benefit of type safety.
Second, the preprocessor is almost just a search and replace engine. For example, in the following code, nothing happens because the preprocessor if statement evaluates to false, since I never defined anything. The preprocessor removes the code in this section. Remember that since the compiler has not run in earnest yet, this removed code will not be compiled. This fact is usually utilized to implement functions for debugging or logging in debug builds. In release builds the preprocessor definition is then manipulated such that the debug code is not included.
#include <stdio.h>
#include <stdlib.h>
int main()
{
#if TRUE
printf("Hello, World!");
#endif
return EXIT_SUCCESS;
}
In fact, the EXIT_SUCCESS macro I used is defined in stdlib.h, and replaced by 0. (EXIT_FAILURE =1).
Back in the day, the preprocessor was used as duct tape, basically, to compensate for faults in C.
For example, since const values can't be used as array sizes, macros were used instead, like this:
// Not valid C89, possibly even C99
const int DEFAULT_BUFFER_SIZE = 128;
char user_input[DEFAULT_BUFFER_SIZE];
// Legal since the dawn of time
#define DEFAULT_BUFFER_SIZE 128
char user_input[DEFAULT_BUFFER_SIZE];
Another significant use of the preprocessor was for code portability, for example:
#ifdef WIN32
// Do windows things
#elif
// Handle other OS
#endif
One trick was to define a generic function and set it to the appropriate OS-dependent one (Remember that functions without the parentheses represent the function's address, not an actual function call), like this:
void RequestSomeKernelAction();
#ifdef WIN32
RequestSomeKernelAction = WindowsVersion;
#else
RequestSomeKernelAction = OtherOSFunction;
#endif
This is all to say that the code you see in header files follows these same rules. If I have the following header file:
#ifndef SRC_INCLUDES_TEST_H
#define SRC_INCLUDES_TEST_H
int square(int a);
#endif /** SRC_INCLUDES_TEST_H */
And I have this main.c file:
#define SRC_INCLUDES_TEST_H
#include "test.h"
int main()
{
int n = square(4);
}
This program will not compile. The square function will not be known to main.c because while I did include the header file where square is declared, my #define SRC_INCLUDES_TEST_H statement tells the preprocessor to copy all the header file contents over to main except those in the block where SRC_INCLUDES_TEST_H is defined, i.e... nothing.
These preprocessor commands can be nested, and there are several, which I highly recommend you look up, if only for historical or pedagogical reasons.
The last point I will make is that while the C preprocessor has its faults, it was a powerful tool in the right hands, and in fact, the first C++ compiler Bjarne Stroustroup wrote was essentially just a preprocessor.

Partly initialising C-arrays from different files

My objective is to instantiate an array in one C-file and have it initialised in different files only through declarative code, i.e., if the following would work, that'd be awesome:
// File1.c
int myArray[2];
// FileA.c
myArray[0] = 123;
// FileB.c
myArray[1] = 345;
The key here is that the code in FileA and FileB is not executed, but what I'd like to see is the compiler picking up these statements to initialise myArray.
What I'm really trying to accomplish here is some form of compilation-based service registration. I.e., in my real code, the array would hold pointers to functions, and my "main" (in File1.c) would not know which specific functions are compiled into the image. Via a different makefile, I would compile different combinations of my files (FileA, FileB, FileC...) and have the functions they implement available to my main via pointers.
Does anyone have an idea how to accomplish this?
You cannot initialize an array piecemeal across several files. You're only allowed one initializer in one file. So, that idea isn't going to work directly.
How can you make it work? You have pointers to functions; I assume they all have the same signature, which can be int function(int arg) for the purposes of this discussion (the details don't matter). It will be defined in a header, and that header will be needed by File1.c.
typedef int (*Function)(int arg);
Each service provider file will have an associated header, FileA.c has a header FileA.h, and so on.
The code that initializes the array could be in File1.c or in a separate file. Wherever it is, it will have to be cognizant of which modules (services) are to be linked:
#include "configuration.h"
#include "FileA.h"
#include "FileB.h"
#include "FileC.h"
Function services[] =
{
#ifdef INCLUDE_SERVICE_A
A_service_function,
#endif
#ifdef INCLUDE_SERVICE_B
B_service_function,
#endif
#ifdef INCLUDE_SERVICE_C
C_service_function,
#endif
};
size_t num_services = sizeof(services) / sizeof(services[0]);
This scheme has the benefit that there is no wasted space in the array. It also won't compile if none of the three services are requested. The build system will ensure that configuration.h includes the correct defines. The per-service headers declare the service functions.
So that gives an outline of a workable scheme.

duplicate symbol error in C

I have the following code layout
header.h
#ifndef _header_h
#define _header_h
void empty(float *array, int l)
{
int i;
for (i=1 ; i<=l ; i++)
{
array[i]=0;
}
}
#endif
and two files (lets call them file1.c and file2.c)
#include "header.h"
void function/*1 or 2*/(){
....
empty(a,b);
....
}
So compiling works fine but the linker command fails as the compiler says that there is a duplicate function definition. How can I avoid that with still using the header file? It is working fine when I only define the function in the header and create another .c file containing the full function. I always thought declaring it in the header is the way to go.
I always thought declaring it in the header is the way to go.
Yes, it is. Declaring it in the header is fine. It is not any good to define it in a header, though. (unless it's static inline, but you probably don't want to do that these days.)
You should never have things in a header that require memory in the running program. This is a rough way of specifying it, but it works pretty well in practice.
In other words, the header should only have the prototype for the function, which is a compile-time thing that doesn't "exist" in the running program (unlike the code of the function itself, which of course exists at runtime):
void empty(float *array, int l);
Then put the code in a separate C file, which you compile and link separately.
You have the function empty defined as a global symbol in the header. This means it will be a visible symbol in all compilation units that include it. There are three general workarounds:
make it a static function
static void empty(...) {...}
put the implementation into a separate compilation unit
in header.h:
void empty(float *array, int l);
in empty.c implement it
instruct your linker to ignore duplicate symbols. This differs from linker to linker, consult man ld.
On OS X: -m flag.
On Linux: -z muldefs

Including header files more than once

#include <stdio.h>
#include <stdio.h>
int main ()
{
printf ("hello world");
return 0;
}
when I compile this, the compiler doesn't give any warning/error for including stdio.h twice. Why is it so? Aren't the functions scanf, printf etc. declared and defined twice now?
Thanks, in advance
Typically, header files are written similar to the below example to prevent this problem:
#ifndef MYHEADER
#define MYHEADER
...
#endif
Then, if included more than once, then 2nd instance skips the content.
In addition to the use of include guards, as pointed out by Mark Tolonen's answer, there is no problem with declaring a function more than once, as long as the declarations are compatible. This is perfectly fine:
int foo(int, char *);
int foo(int a, char *p);
extern int foo(int x, char y[]);
In fact, since every definition is also a declaration, whenever you "forward-declare" a function declared in the same file, you are declaring the function twice.
What is not OK is to create multiple external definitions of a function; but well-written header files should not create external definitions - only declarations. The (single) definition of the printf and scanf functions should be in an object file, which is linked with your program when it is built.
No, the header files usually define a flag and then use #ifndef to include themselves only if the flag was undefined.
Open one up and see.
As an aside, doing the "#ifndef" trick is appropriate for headers used by other people (like the standard headers).
If you need the #ifndef for a "private" program, then you are doing it "wrong". That is, you can and should organize headers within a project so they are not included more than once.
One reason that this is helpful is that keeps headers you think you have deleted from popping up again.
Since you can't control how public headers are used, this trick is reasonable for public headers. This trick is completely unnecessary for private headers.

Define a function before main?

Are function declarations/prototypes necessary in C99 ?
I am currently defining my functions in a header file and #include-ING it in the main file. Is this OK in C99 ?
Why do most programmers declare/prototype the function before main() and define it after main() ? Isn't it just easier to define them before main and avoid all the declarations/prototypes ?
Contents of header.h file:
int foo(int foo)
{
// code
return 1;
}
Contents of main file:
#include <stdio.h>
#include "header.h"
int main(void)
{
foo(1);
return 0;
}
How and where to prototype and define a function in C :
Your function is used only in a specific .c file :
Define it static in the .c file. The function will only be visible and compiled for this file.
Your function is used in multiple .c files :
Choose an appropriate c file to host your definition (All foo related functions in a foo.c file for example), and have a related header file to have all non-static (think public) functions prototyped. The function will be compiled only once, but visible to any file that includes the header files. Everything will be put together at link time. Possible improvement : always make the related header file, the first one included in its c file, this way, you will be sure that any file can include it safely without the need of other includes to make it work, reference : Large Scale C++ projects (Most of the rules apply to C too).
Your function is inlinable (are you sure it is ?) :
Define the function static inline in an appropriate header file. The compiler should replace any call to your function by the definition if it is possible (think macro-like).
The notion of before-after another function (your main function) in c is only a matter of style. Either you do :
static int foo(int foo)
{
// code
return 1;
}
int main(void)
{
foo(1);
return 0;
}
Or
static int foo(int foo);
int main(void)
{
foo(1);
return 0;
}
static int foo(int foo)
{
// code
return 1;
}
will result in the same program. The second way is prefered by programmers because you don`t have to reorganize or declare new prototypes every time you declare a new function that use the other ones. Plus you get a nice list of every functions declared in your file. It makes life easier in the long run for you and your team.
People typically do it because it's easier to do with multiple files. If you declare in a header then you can just #include that header anywhere you need those functions. If you define them in a header and then include in another translation unit, bang.
Function declarations are required in C99. Function prototypes are not required in C99.
Declaring functions before the point of the call and defining them after the point of the call is a popular approach to structuring the program code. However, this is in no way what the "most" programmers do. On the contrary, a more popular approach is to define function before the point of the first call, in which case the separate declaration is not necessary. This approach requires less maintenance, which is why it is more popular than what you describe.
Separate declarations/definitions are normally used with external functions only, i.e. with functions used across several translation units. Such functions are declared in header files and defined in implementation files.
You should only ever define inline functions in headers. Although you can have extern inline functions, the common case is static inline.
Rule of thumb for header files:
function declarations should be extern
function definitions should be static inline
variable declarations should be extern
variable definitions should be static const
As C. Ross asked for it, here's reasoning behind it: A resource with external linkage should only ever be defined once[1]. It follows that definitions should not reside in header files, which are intended to be included in more than one place.
Having static definitions in header files won't lead to any problems, but is generally frowned upon because the code has to be compiled more than once and will be present in different object files, which will increase the executable size (assuming the linker isn't smart enough to figure out the code duplication).
The common exceptions to this rule are constants and inline functions, which are supposed to be visible to the compiler in each translation unit to make further optimizations possible.
Note: [1] This does not apply to inline functions with external linkage, but as it's unspecified which of the multiple definitions of an inline function will be used in the evaluation of a function designator, they are mostly useless
Your approach is fine for small programs. Header files are meant for declarations and constant definitions - they provide an interface to the program they "encapsulate". Headers are meant as an interface for other program units.
In case you have more .c files, forward declarations and header files are necessary, because a C function can be defined only once for the whole program (search for one definition rule), even though you may use the function anywhere (in any .c file). If you defined it in a header, it would get included in all .c files you use it in and result in multiple definitions.
It's quicker to do like that, but I personally prefer to have the main function at the beginning of the main file, and put the other functions in other files or below main.
Note that in your example you should avoid declaring foo() in a header file: you won't be able to include it in two different source files. Declare it in the C file containing main(); you won't need to define it elsewhere unless you're referring to it from some other files.
Yes, it is easier to define them before main. If you only want to use these functions from within the file, a prototype is not necessary. In that case however, you can also prepend the "static" keyword before the function definition. (In the C file.) That will ensure the function is not visible to other files. (At link time.)
Do not put static keywords in include files.
You should always prototype.
The reasons for this are;
methodical prototyping produces a succinct list in header files of the functions in the code - this is invaluable to future readers
in anything but the simplest projects, many functions will not have visibility prior to main.
main should be the first function in its file; it's easier for the reader, since we read down, not up
Why do most programmers declare/prototype the function before main() and define it after main() ?
Merely because most humans read sequentially. Start a story from the beginning, not the middle. Not necessary, just intuitive.
Of course if the code being prototyped is in a separate compilation unit, the prototypes are necessary.
It is always a good practice to declare the functions in either before main or in a separate header file which will be included in other c files where we have used that function. By doing this we can easily identify all the functions declared/defined in that .C or .H files. And we should use extern key word before declaring the function in header file.

Resources