Structured module interface for C - c

I want to improve my C code style a bit and as well encapsulate my code a bit more. Furthermore, the interface to my modules should be clear and easy to handle.
In my project I have several modules containing the different functions.
modul_1.c
static int modul_1_func_2(void);
void modul_1_func_1(void) { ... }
int modul_1_func_2(void) { ... }
void modul_1_func_3(int) { ... }
modul_1.h
void modul_1_func_1(void);
void modul_1_func_3(int);
There are local and global module-function.
With a struct, it should be possible to call the functions from the main like
modul_1.modul_1_func_1();
In know that I have to use function pointers within the structure, but I don't know how to initialize them.
I don't want a a dynamic pointer where I have to change the address each time before I use it. I want to have several pointers within the structure — one for each global function.
I already tried this without success:
typedef void (*func_1_temp)(void);
typedef void (*func_3_temp)(int);
struct {
func_1_temp func_1;
func_3_temp func_3;
} HMI = {
func_1 = &modul_1_func_1(),
func_3 = &modul_1_func_3()
};
Does anyone know what I have to do that my dreams come true?
I hope to get a clear interface with this approach.
For other ideas I am thankful as well.

The name of a function is, at least in this context, directly usable as a
pointer to the function.
mod.h
void modul_1_func_1(void);
void modul_1_func_3(int);
granicus% cat mod.c
static int modul_1_func_2(void);
mod.c
void modul_1_func_1(void) { return; }
int modul_1_func_2(void) { return 1; }
void modul_1_func_3(int x) { modul_1_func_2(); return; }
granicus% cat main.c
#include "mod.h"
typedef void (*func_1_temp)(void);
typedef void (*func_3_temp)(int);
main.c
int main(void) {
struct {
func_1_temp func_1;
func_3_temp func_3;
} HMI = {
modul_1_func_1,
modul_1_func_3,
};
HMI.func_1();
return 0;
}
Compiling on my system with gcc -Wall main.c mod.c gives no errors or warnings.

Related

How to use macro for calling function?

I want to call function according to func_name string.
My code is here below:
#define MAKE_FUNCNAME func_name##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
char func_name[30] = "print_";
call_func(MAKE_FUNCNAME);
return 0;
}
But this code doesn't work. I want code to work like call_func(print_hello). But preprocessor treated my code like call_func("print_hello"). How to use macro in C to make my exception? Or is it not possible using C?
Then problem with your code is that the value of func_name is only known at run-time.
You can however to it like this:
#define MAKE_FUNCNAME(FUNCNAME) FUNCNAME##hello
void call_func(void* (*func)(void))
{
func();
}
void *print_hello(void)
{
printf("print_hello called\n");
}
int main(void)
{
call_func(MAKE_FUNCNAME(print_));
return 0;
}
But it is not possible to use a string value within macro parameters like in your code snippet.
If you want to get call functions with their names using string values you can use a table to store function pointer with function names like this:
struct {
const char *name;
void (*ptr)(void);
};
You can use an array of this structure to find out the function pointer at run-time using a string value. This is the most common solution to using run-time strings to call functions using their names.
You can't do that. The value of func_name is known at run-time (even though it is a const char *), while you want to determine what to call at precompile-time. You should turn your cpp macro into something different (such as an if/switch statement or using an indirection).
Maybe you could have a look to dlsym().
Not sure I really understand the question, but if you want to "build" the function name at runtime and then call the corresponding function, it should be possible with dlsym()
/* compile with: gcc example.c -ldl -rdynamic */
#include <dlfcn.h>
#include <stdio.h>
int print_hello(void)
{
return printf("hello\n");
}
int main(int argc, char *argv[])
{
const char *name = "print_hello";
if (argc == 42)
print_hello(); /* for compiler not to remove print_hello at
* compile time optimisation in this example*/
void *handle = dlopen(NULL /* self */, RTLD_NOW);
int (*f)(void) = dlsym(handle, name);
f();
return dlclose(handle);
}

Inlined Setter and Getter functions in C

In C++ I can have a getter function declared inline in a header file:
class Cpp_Example
{
public:
unsigned int get_value(void)
{ return value;}
private:
unsigned int value;
};
By including this header file, client methods and functions can use the getter function to access a private variable.
I'm looking to model this concept in the C language:
hello.h:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
inline void Print_Hello(void)
{
extern const char hello_text[32];
puts(hello_text);
}
inline void Print_Value(void)
{
extern unsigned int value;
printf("Value is: %d\n", value);
}
#endif // HELLO_H
hello.c:
const char hello_text[32] = "Hello World!\n";
static unsigned int value = 5U;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main(void)
{
Print_Hello();
Print_Value();
// puts(hello_text);
return EXIT_SUCCESS;
}
I get a linker error from gcc:
$ gcc -o main.exe main.c hello.c
/tmp/cc41ZB8H.o:main.c:(.rdata$.refptr.value[.refptr.value]+0x0): undefined reference to `value'
collect2: error: ld returned 1 exit status
Is there a way to have an inline function (in a header file) access a static variable in another translation unit?
Or is there a way to implement an inlined getter function?
I'm using IAR Embedded Workbench, ARM7TDMI processor on an embedded platform.
The gcc compiler is used to testing concepts on the PC.
Edit 1: Background
I'm looking to optimize getter calls that are inside a critical section. The objective is to reduce the time spent in the critical section.
Edit 2: No Globals
The Coding Guidelines our shop uses states no global variables.
Also, this system is an RTOS running MicroCOSII.
First of all, the same way you have private variables in C++, you probably mean to have private variables for a struct rather than global. With that assumption, here's one model you can use:
/* some_type.h */
struct some_type
{
int public_data;
void *privates;
};
struct some_type_privates
{
char hello[32];
int value;
};
inline const char *get_hello(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->hello;
}
inline int get_value(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->value;
}
/* similarly for setters */
The same way that your private variables and their getters and setters are in the header file, you can do it in C, too.
On the side, I'd like to recommend not to try coding C++ in C. While C++ likes to complicate things a lot to prevent the idiot from breaking something, C on the other hand trusts the programmer has some degree of intelligence. Whether these assumptions are justified are not the matter of discussion. But what I mean to say is that the spirit of C is not to hide a variable so that the programmer doesn't mistakenly access it.
That said, this is how you would normally make a struct in C:
struct some_type
{
int public_data;
char hello[32]; /* read only */
/* internal */
int value;
};
(with enough documentation of course) which tells any programmer that she shouldn't write over hello but can freely read it (what you were trying to achieve by an inline getter). It also tells that value is private so the programmer shouldn't read or write it.
You can see this in many POSIX functions that take or return a struct. Some that don't need to control the access let you freely modify the struct, such as stat. Some that do need to check the input have setters, such as pthread_attr_*.
You need to remove the static keyword. static definitions are local to the compilation unit.
As Shabbas wrote, it doesn't really work that way in C.
The keyword inline implies static, even if the compilers doesn't actually inline it. If it is such a short function, it will probably inline it. But the point is, if it would not be static, it could not even consider inlineing it, as the function would need to be visible externally, it would need an address, which an inlined function doesn't have.
Since it is local in your compilation unit, it can only work on stuff known inside that compilation unit. Thus you need to say something about that value variable, much like you do need to mention it in the C++ header as well, only in C there is no such thing as private .
You can not have Inlineing and data hiding in the same case, neither in C, nor in C++.
Assuming you mean for global, statically-allocated variables you can do this:
In Example.h:
#ifndef Example
#define Example
extern int getValue();
#endif
In Example.c
#include "Example.h"
static int value;
inline int getValue() {
return value;
}
// All the functions in Example.c have read/write access
In UsesValueExample.c
#include "Example.h"
// All the functions in UsesValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
If you want to get fancy and force all code to access through a getter and setter, e.g. if the variable is volatile and you want to heavily encourage all the methods to use a local cache of the variable to avoid the overhead of accessing the volatile, then:
In VolatileExample.h:
#ifndef VolatileExample
#define VolatileExample
extern int getValue();
#endif
In VolatileExample.c
#include "VolatileExample.h"
void setValue(); // Forward declaration to give write access
// All the functions in VolatileExample.c have read/write access via getters and setters
void addToValuesAndIncrementValue(int const values[], int const numValues) {
int value = getValue(); // Cache a local copy for fast access
// Do stuff with value
for (int i = 0; i < numValues; i++) {
values[i] += value;
}
value++;
// Write the cache out if it has changed
setValue(value);
}
// Put the definitions after the other functions so that direct access is denied
static volatile int value;
inline int getValue() {
return value;
}
inline void setValue(int const newValue) {
value = newValue;
}
In UsesVolatileValueExample.c
#include "VolatileExample.h"
// All the functions in UsesVolatileValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
Here is a pattern I've been using to hide global variables.
Inside some header file, such as module_prefix.h, you declare the following:
typedef int value_t; // Type of the variable
static inline value_t get_name(void) __attribute__((always_inline));
static inline void set_name(value_t) __attribute__((always_inline));
static inline value_t get_name(void) {
extern value_t module_prefix_name;
return module_prefix_name;
}
static inline void set_name(value_t new_value) {
extern value_t module_prefix_name;
module_prefix_name = new_value;
}
/* Note that module_prefix_name is *no longer* in scope here. */
Then of course you have to define module_prefix_name in some compilation unit, without the static keyword, as discussed above, e.g. in module_prefix.c you have the following:
#include "module_prefix.h"
value_t module_prefix_name = MODULE_PREFIX_NAME_INIT_VALUE;
This is essentially the same pattern that Thomas Matthews tried to use, drilling down to the essence and making sure that the compiler inlines the functions always and does not unnecessarily generate explicit function bodies. Note the use of module_prefix as poor man's name spaces.

C: initialising global constants with external linkage

I want to statically initialise a struct that will be visible from all files which include some header.
The actual intention is to run lists of functions specified at compile time, which is why I want to initialise statically. I'd like to put the lists where they belong, in the file in which they are declared or defined.
Contrived example:
general.h:
struct Widget { int (*a)(); };
foo.h:
int oof1(void);
int oof2(void);
foo.c:
#include "foo.h"
int oof1(void) { return 1; }
int oof2(void) { return 2; }
struct Widget foo_widgets[] = { {oof1}, {oof2} };
bar.c:
#include "foo.h"
#include "baz.h"
struct Widget *foo_widgets;
struct Widget *baz_widgets;
struct WidgetsContainer {
struct Widget *widget_list;
} wlists[] =
{
{ foo_widgets },
{ baz_widgets }
};
void usage(void) { ... ; process (wlists[i].widget_list); ... }
This obviously doesn't work because "the initialiser element is not constant" - This is because when the compiler is translating bar.c, it thinks it doesn't know the location of foo_widgets (or bar_widgets).
But since bar.c #includes foo.h anyway, it's always compiled alongside foo.c:
gcc foo.c baz.c bar.c
So I'm hoping there's a way of reflecting this in the source code.
I can't declare foo_widgets in foo.h, because then I wouldn't be able to initialise it without defining it multiple times (as foo.h is included in more than one file).
Inelegant workaround
foo.h:
...
Widget *get_foos(void) { return foo_widgets; }
bar.c:
...
struct Widget_lists {
struct Widget (*widget_list)();
} wlist[] =
{
{ get_foos },
{ get_bazes }
};
void usage(void) { ...; process(wlist[i].widget_list()); ... }
Is there a better way?
You want to have a global variable that you can reach anywhere ... To do so you have to declare it as an external variable in the appropriate header.
Here, it should be done as follows :
In foo.h :
/* ... */
int oof1(void);
int oof2(void);
extern int (*foo_widget)(void)[2];
In foo.c :
int (*foo_widget)(void)[2] = {{oof1}, {oof2}};
By doing so, when including "foo.h", the foo_widget variable will be known (and expected to be defined somewhere else - in foo.c here - ).
To be more precise ... Any piece of code that needs to make use of foo_widget must have the line extern int (*foo_widget)(void)[2]; somewhere, be it in an included header (the smarter way) or just a line at the beginning of the .c file.
Of course, if you cannot know in advance the number of widgets you can have, you are likely to need a dynamic data structure such as a linked list or a tree (ordered and balanced if possible ;) ) to store them. The extern variable is likely to be a regular pointer dynamically allocated when needed. But the definition line is still needed, so in this case you might have something like struct my_struct *pointer = NULL; in the appropriate source file.
Note : I took the freedom to replace your struct Widget with a common function pointer to get the initialization simpler.

Hide struct definition in static library

I need to provide a C static library to the client and need to be able to make a struct definition unavailable. On top of that I need to be able to execute code before the main at library initialization using a global variable.
Here's my code:
private.h
#ifndef PRIVATE_H
#define PRIVATE_H
typedef struct TEST test;
#endif
private.c (this should end up in a static library)
#include "private.h"
#include <stdio.h>
struct TEST
{
TEST()
{
printf("Execute before main and have to be unavailable to the user.\n");
}
int a; // Can be modified by the user
int b; // Can be modified by the user
int c; // Can be modified by the user
} TEST;
main.c
test t;
int main( void )
{
t.a = 0;
t.b = 0;
t.c = 0;
return 0;
}
Obviously this code doesn't work... but show what I need to do... Anybody knows how to make this work? I google quite a bit but can't find an answer, any help would be greatly appreciated.
TIA!
If you're using gcc you can use the constructor attribute,
void runs_before_main(void) __attribute__((constructor))
{
...
}
From the gcc documentation
The constructor attribute causes the
function to be called automatically
be- fore execution enters main ().
Similarly, the destructor attribute
causes the function to be called
automatically after main () has
completed or exit () has been called.
Functions with these attributes are
useful for initializing data that will
be used implicitly during the
execution of the program.
You may provide an optional integer
priority to control the order in which
constructor and destructor functions
are run. A constructor with a smaller
priority number runs before a
constructor with a larger priority
number; the opposite relationship
holds for destructors. So, if you have
a constructor that allocates a
resource and a destructor that
deallocates the same resource, both
functions typically have the same
priority. The priorities for
constructor and destructor functions
are the same as those specified for
namespace-scope C++ objects
If you want to hide a struct from users, declare the struct in a header but define it in the c file, passing around pointers. As an example:
// foo.h
typedef struct private_foo foo;
foo * create_foo(void);
void free_foo(foo * f);
// foo.c
struct private_foo {
int i;
}
foo * create_foo(void){
foo * f = malloc(sizeof(*foo));
if (f) f->i = 1;
return f;
}
...
foo->i can then not be accessed outside foo.c.
If you want the client code to be able to use "t.a = ...", then you cannot hide the struct definition. What you want is called an opaque type, that will look something like this:
public.h:
struct foo;
set_a( struct foo *, int );
struct foo * new_foo(void);
main.c:
#include <public.h>
int main( void )
{
struct foo *k;
k = new_foo();
set_a( k, 5 );
}
The structure definition is only available to the library. If you do not make the library source code available, it is possible to completely hide it from the users of the library.
There is no portable way in C to ensure your code will run before main(). What I would do is just maintain an initialised flag in your library, set to false, and then refuse to do anything until your init function has been called.
As in:
static int initialised = 0;
int init (void) {
// do something.
initialised = 1;
return ERR_OK;
}
int all_other_functions (void) {
if (!init)
return ERR_NOT_INITED;
// do something.
return ERR_OK;
}

Storing a global struct variable inside another global struct in C

I’m trying to figure out a way to use nested global structs as a sort of API namespacing for my C library.
Specifically, I want to expose a single Primary ‘namespacing struct,’ that contains other such structs (such as Primary.Secondary), that themselves contain function pointers (Primary.Secondary.a_function()).
I’ve abstracted out the following (relatively) simple example of what I want to do:
main.c:
#include "Primary.h"
int main () {
Primary.Secondary.a_function();
return 0;
}
Primary.h:
#if !defined(SECONDARY_H)
# include "Secondary.h"
#endif
struct Primary_struct {
struct Primary__Secondary_struct Secondary;
} extern Primary;
Primary.c:
#include "Primary.h"
struct Primary_struct Primary = {
.Secondary = Primary__Secondary
};
Secondary.h:
struct Primary__Secondary_struct {
void (*a_function) (void);
void (*another_function) (void);
} extern Primary__Secondary;
Secondary.c:
#include "Secondary.h"
#include <stdio.h>
void Primary__Secondary__a_function (void);
void Primary__Secondary__another_function (void);
struct Primary__Secondary_struct {
.a_function = Primary__Secondary__a_function,
.another_function = Primary__Secondary__another_function
} extern Primary__Secondary;
void Primary__Secondary__a_function(void) {
Primary.Secondary.another_function();
}
void Primary__Secondary__another_function(void) {
printf("run!\n");
}
When I attempt to compile this, I run into the following compiler error:
> C -O0 Primary.c Secondary.c main.c
Primary.c:3:33: error: initializer element is not a compile-time constant
struct Primary_struct Primary = {
^
1 diagnostic generated.
I should note, ideally, both the Primary and Primary__Secondary variables would be const. I was worried that the added complexity would exacerbate the problem… so for now, I’ve left that aspect out.
The problem seems to be that, for some reason, even when set as const, and containing only elements present at compile time, the Primary__Secondary struct is not a compile-time constant, and thus cannot be stored in another struct at compile-time. I can probably work around this by setting up all of the interfaces at runtime, but… that seems like a really hacky solution. I’m looking for any alternative solutions to this problem, that the more C-fu of you than I can come up with.
(Note: This is related to this question, but is substantially different, and quite a bit more specific.)
What you're trying can't be done; sorry. Here's a condensed example:
#include <stdio.h>
int a = 5;
int b = a;
int main(int argc, char *argv[])
{
printf("Hello, world!\n");
return 0;
}
Compiling this code gives the error:
main.c:4: error: initializer element is not constant
Because the compiler doesn't know how to make the assignment int b = a at compile time. It's just the way the language works!
You had some odd notations in your code - I've converted them to a more orthodox form. Also, as a general rule, avoid using double-underscore in names; in C++ this is absolutely necessary.
You also need to use a pointer to the embedded structure - then the code will run:
Primary.h
//Primary.h:
#ifndef PRIMARY_H
#define PRIMARY_H
#include "Secondary.h"
struct Primary_struct {
struct Primary_Secondary_struct *Secondary;
};
extern struct Primary_struct Primary;
#endif // PRIMARY_H
Secondary.h
//Secondary.h:
#ifndef SECONDARY_H
#define SECONDARY_H
struct Primary_Secondary_struct {
void (*a_function)(void);
void (*another_function)(void);
};
extern struct Primary_Secondary_struct Primary_Secondary;
#endif // SECONDARY_H
Primary.c
//Primary.c:
#include "Primary.h"
struct Primary_struct Primary = {
.Secondary = &Primary_Secondary
};
Secondary.c
//Secondary.c:
#include "Secondary.h"
#include "Primary.h"
#include <stdio.h>
void Primary_Secondary_a_function(void);
void Primary_Secondary_another_function(void);
struct Primary_Secondary_struct Primary_Secondary = {
.a_function = Primary_Secondary_a_function,
.another_function = Primary_Secondary_another_function
};
void Primary_Secondary_a_function(void) {
Primary_Secondary.another_function();
printf("hide!\n");
}
void Primary_Secondary_another_function(void) {
printf("run!\n");
}
main.c
//main.c:
#include "Primary.h"
int main () {
Primary.Secondary->a_function();
return 0;
}
This generates:
run!
hide!
I ended up going with a runtime approach, at least for now. I might try a pointers approach (suggested by Jonathan Leffler above) later on, and see if I end up with a less complex / more comprehensible codebase… but this works for now.
I use clang (and gcc)’s __attribute__((constructor)) extension to set up the structs’ relationships at runtime; the same could be achieved more portably (but less cleanly) with some code in main().
I’d offer a little more explanation, but it’s 4AM here… heh. I’ve spent all day on this >,<
main.c:
#include "Package.h"
int main () {
Package.One.a_function();
Package.One.another_function();
Package.Two.a_function();
Package.Two.another_function();
return 0;
}
Package.h:
#define PACKAGE_H
#if !defined(ONE_H)
# include "One.h"
#endif
#if !defined(TWO_H)
# include "Two.h"
#endif
// It seems this is broken, at least in `clang`
// #if __has_feature(attribute_constructor)
# define constructor __attribute__((constructor))
// #endif
struct Package_struct {
struct Package__One_struct One;
struct Package__Two_struct Two;
};
struct Package_struct extern Package;
Package.c:
#include "Package.h"
struct Package_struct Package = {};
One.h:
#define ONE_H
struct Package__One_struct {
void (*a_function) (void);
void (*another_function) (void);
};
struct Package__One_struct extern Package__One;
One.c:
#include "One.h"
#include "Package.h"
#include <stdio.h>
void Package__One__a_function (void);
void Package__One__another_function (void);
struct Package__One_struct Package__One = {
.a_function = Package__One__a_function,
.another_function = Package__One__another_function
};
void constructor Package__register_One(void) {
Package.One = Package__One; }
void Package__One__a_function(void) {
Package.One.another_function();
}
void Package__One__another_function(void) {
printf("one!\n");
}
Two.h:
#define TWO_H
struct Package__Two_struct {
void (*a_function) (void);
void (*another_function) (void);
};
struct Package__Two_struct extern Package__Two;
Two.c:
#include "Two.h"
#include "Package.h"
#include <stdio.h>
void Package__Two__a_function (void);
void Package__Two__another_function (void);
struct Package__Two_struct Package__Two = {
.a_function = Package__Two__a_function,
.another_function = Package__Two__another_function
};
void constructor Package__register_Two(void) {
Package.Two = Package__Two; }
void Package__Two__a_function(void) {
Package.Two.another_function();
}
void Package__Two__another_function(void) {
printf("two!\n");
}

Resources