Compile-time check struct with function pointers to validate assignments - c

I'm wondering if the following is possible:
I have a namespace-style struct setup, filled with just function pointers. These are provided in the header file like so:
typedef struct {
int32_t(*const event_construct)(struct sync_event* evt);
int32_t(*const event_destroy)(struct sync_event* evt);
int32_t(*const event_set)(struct sync_event* evt);
int32_t(*const event_wait)(struct sync_event* evt);
} namespace_sync;
extern namespace_sync const sync;
and then in the relevant source file, after all the function implementations:
...
namespace_sync const sync = {
sync_event_construct,
sync_event_destroy,
sync_event_set,
sync_event_wait
};
Say I want to add an extra function not at the end; I add it to the struct and source file, but forget to assign it. Because the function declarations match, a warning isn't generated for it, and the compiler (at least in this example, vs2013) doesn't provide a hint that there's an issue.
I've got compile-time assertion checks available, but not sure if I can verify this particular aspect, since the struct size is accurate. If vs2013 can't work with it - I'm aware it's an abysmal C compiler(!) - the newest versions of gcc will also be used, so I could limit the functionality to one compiler.

One solution going forward would be to use designated initializers:
namespace_sync const sync = {
.event_construct = sync_event_construct,
.event_destroy = sync_event_destroy,
.event_set = sync_event_set,
.event_wait = sync_event_wait
};
Any unlisted members will default to null pointers.
I would advise to not add members into the middle of a struct, because it is difficult to be sure that you have correctly updated any code that was relying on the old struct layout. However, if you really do want to do this, then one way to have the compiler indicate to you where all the uses of the struct are is to change the struct name:
typedef struct {
// ...
} namespace_sync_2;
Then the code namespace_sync const sync will cause a compilation error. This alerts you to the fact that this piece of code requires a code review to make sure that it will work correctly with the new struct layout.

Related

C++11, wrapper class for handling different versions of C struct versions

EDIT:
I think the version is known at run-time instead of compile-time so I'm not able to add it as a compile option to the gcc cmd. Which is why I have to support both versions based on whatever version the hardware reports back.
So I'm dealing with firmware where I am required to support multiple definitions for versions of the same C struct. We created our own header file as defined by the interface documentation of a memory controller based on the vendor's C struct definition.
// For simplicity lets pretend that this is the struct for version 1
typedef struct __attribute__((packed)) ver1 {
int x;
int y;
} ver1;
I also have an existing API that uses this interface already that needs to be replaced by some sort of class wrapper (I believe), or a wrapper that plays well with the existing API.
void function_call(ver1 v1);
Only one instance (ver 1 or ver 2) of the struct can exist at any time
ver 1 for a certain fw version, and ver 2 after a certain fw version
ver2 is my extended version of ver1, I am naming it as ver2 for the hope of using some sort of factory to select the right C-style struct.
typedef struct __attribute__((packed)) ver2 {
int x;
int y;
int w; // new
int z; // new
} ver2;
Before creating a ver 2 I was looking into options such as the decorator or adaptor design pattern I could try a fancy CRTP template style I found on Hands-On Design Patterns but for simplicity, I'll illustrate with this scheme where I could possibly "add-on" to ver1:
struct ver2 : public ver1 {
int w;
int z;
}
But then I learned that C++ doesn't guarantee the same class layout
C struct Inheritance vs C++ POD struct Inheritance
and potential alignment issues (I'm not too familiar with it) so I don't think it is a real option for me to use.
I found this example on stackoverflow but I don't like the idea of adding include headers in the struct How to handle conflicting struct definitions in a C application.
There is a similar example here using a similar base class
C++ design for multiple versions of same interface (enumerations / structures in header files) which I don't think I can even use due to inheritance impact on the class layout.
Unless there is a valid reason to use the techniques of the links above, I was considering a wrapper class that returns the right version based on a selector. First I'll define a free function to leverage this.
int get_fw_version(int target);
I'm working on C++11 so I'm limited on auto return type deduction and below is just some draft code I'm trying to think up, not complete, doesn't compile, just illustrating my thought process. I haven't considered composition yet since IDK how that will quite work. Looking for ideas.
int main() {
// Roughly how I would like to use it...
const int fw_ver = get_fw_version(target);
auto ver_inst = ver_factory(fw_ver);
function_call( ver_inst.get_data() );
return 0;
}
I am not sure if I can do this without polymorphism where the base class gets ver1 and but the derived class has ver2.
Rough idea where I am at, I tried doing CRTP but I hit the problem that the base class needs to be a template and I can't use a heterogeneous base type (e.g. shared_ptr). Trying the non-CRTP way IDK how to set up the abstract base class with the get_data() method. Without the compiler complains saying that the base doesn't have a get_data method, which, makes sense
// I can't figure out how to add T get_data() here without adding a template param. This base function is really to delegate common member methods and trying to keep a common base for polymorphism.
class base {
virtual ~base() = 0;
// ?? get_data() = 0 or some other method
};
class ver1_derived : public base
{
ver1 data;
public:
ver1_derived() = default;
ver1 get_data() {
return data;
}
};
class ver2_derived : public base
{
ver2 data;
public:
ver2_derived() = default;
ver2 get_data() {
return data;
}
};
// should be using unique_ptr but I can't at work....
shared_ptr<base> ver_factory(const int fw_ver) {
if(fw_ver <= 1)
return make_shared<ver1_derived>();
return make_shared<ver2_derived>();
}
I ended up giving up on an inheritance schemed and ended up taking two different code paths based on the template type.
So
if(fw_ver <= 1)
function_call<ver1>();
} else {
function_call<ver2>();
}

why handle to an object frequently appears as pointer-to-pointer

What is the intention to set handle to an object as pointer-to pointer but not pointer? Like following code:
FT_Library library;
FT_Error error = FT_Init_FreeType( &library );
where
typedef struct FT_LibraryRec_ *FT_Library
so &library is a FT_LIBraryRec_ handle of type FT_LIBraryRec_**
It's a way to emulate pass by reference in C, which otherwise only have pass by value.
The 'C' library function FT_Init_FreeType has two outputs, the error code and/or the library handle (which is a pointer).
In C++ we'd more naturally either:
return an object which encapsulated the success or failure of the call and the library handle, or
return one output - the library handle, and throw an exception on failure.
C APIs are generally not implemented this way.
It is not unusual for a C Library function to return a success code, and to be passed the addresses of in/out variables to be conditionally mutated, as per the case above.
The approach hides implementation. It speeds up compilation of your code. It allows to upgrade data structures used by the library without breaking existing code that uses them. Finally, it makes sure the address of that object never changes, and that you don’t copy these objects.
Here’s how the version with a single pointer might be implemented:
struct FT_Struct
{
// Some fields/properties go here, e.g.
int field1;
char* field2;
}
FT_Error Init( FT_Struct* p )
{
p->field1 = 11;
p->field2 = malloc( 100 );
if( nullptr == p->field2 )
return E_OUTOFMEMORY;
return S_OK;
}
Or C++ equivalent, without any pointers:
class FT_Struct
{
int field1;
std::vector<char> field2;
public:
FT_Struct() :
field1( 11 )
{
field2.resize( 100 );
}
};
As a user of the library, you have to include struct/class FT_Struct definition. Libraries can be very complex so this will slow down compilation of your code.
If the library is dynamic i.e. *.dll on windows, *.so on linux or *.dylib on osx, you upgrade the library and if the new version changes memory layout of the struct/class, old applications will crash.
Because of the way C++ works, objects are passed by value, i.e. you normally expect them to be movable and copiable, which is not necessarily what library author wants to support.
Now consider the following function instead:
FT_Error Init( FT_Struct** pp )
{
try
{
*pp = new FT_Struct();
return S_OK;
}
catch( std::exception& ex )
{
return E_FAIL;
}
}
As a user of the library, you no longer need to know what’s inside FT_Struct or even what size it is. You don’t need to #include the implementation details, i.e. compilation will be faster.
This plays nicely with dynamic libraries, library author can change memory layout however they please, as long as the C API is stable, old apps will continue to work.
The API guarantees you won’t copy or move the values, you can’t copy structures of unknown lengths.

Accessing structure in structure through pointer

Brief description:
I write something to structure through pointer but something else gets written. I work in atollic true studio 8.1, programming an STM32F415RG MCU.
The strangest thing is that even if I look in variables and expression window, I can see the same structure with different values.
Same variable in two windows with different values
Now to elaborate a bit (I am going to simplify a lot of stuff to make it more readable).
I have my protocol handle type defined:
typedef struct
{
RS485DriverHandle master_rs485;
} EscomProtocolHandle;
My RS485 driver handle is defined as follows:
typedef struct
{
UART_HandleTypeDef* uart_handle;
TransceiverState transceiver_state;
GPIO_TypeDef* dir_gpio;
uint16_t dir_pin;
} RS485DriverHandle;
I have created my protocol handle as a global variable:
static EscomProtocolHandle hprot1;
I pass it to my protocol init function which takes a pointer to handle as an argument:
Escom_Protocol_Init(&hprot1);
Init function passes it to RS485 driver init function which takes pointer to RS485 handle as an argument (this call is simplified a lot):
void Escom_Protocol_Init(EscomProtocolHandle* protocol_handle)
{
RS485_Init(&protocol_handle->master_rs485)
}
RS485 init function sets default values:
void RS485_Init(RS485DriverHandle* rs485_handle, UART_HandleTypeDef* uart_handle,
GPIO_TypeDef* dir_gpio, uint16_t dir_pin)
{
/* default = listening */
rs485_handle->uart_handle = uart_handle;
rs485_handle->dir_gpio = dir_gpio;
rs485_handle->dir_pin = dir_pin;
ReceiverOutputEnable(rs485_handle);
rs485_handle->transceiver_state = kReceiving;
}
Now if I look at the local variable rs485_handle, the values are set correctly. But If I look at my handle hprot1, the values don't match. Even though rs485_handle's address matches the address of master_rs485 member of the hprot1 handle.
P.S.: I have not messed with the packing (#pragma pack) of any of the above mentioned structures, so that should not be an issue.
Got it!
There was a seemingly unrelated header file that had a structure prototype in it which was packed(1) and there was no #pragma pack() after the structre prototype to restore the packing to default state. Thus RS485DriverHandle was packed differently in different places. In both Escom_Protocol_Init and RS485_Init the address of the handle structure was the same, but the packing was different so for example the address of GPIO_TypeDef* dir_gpio member was 0x200000D6 in Escom_Protocol_Init but was 0x200000D9 in RS485_Init.

Wrapper function in C using structure of function pointers

I have to write code in C where the user has to have flexibility in choosing any existing DB, write to files, or implement their own storage mechanism. I need wrapper functions that redirect to the right functions corresponding to the storage mechanism selected at runtime or compile time. Say my storage options are FLATFILE and SQLDB and my wrapper function is insert(value). So, if I select FLATFILE as my storage, when I call the wrapper function insert(value), it should in turn call the function that writes to a file. If I choose a SQLDB, insert(value) should call the function that insert the values in the data base.
I know I can somehow use a structure of function pointers to do wrapper functions, but I have no idea how.
Does anyone know of any docs, links, examples, etc I could refer to, to understand and implement something like this? Any pointers will be appreciated. Thanks!
Thanks!
#define BACKEND_FLATFILE 0
#define BACKEND_SQLDB 1
void insert_flatfile(const t_value *v) {
...
}
void insert_sqldb(const t_value *v) {
...
}
void (*insert_functions[]) (const t_value *) = {
insert_flatfile,
insert_sqldb,
};
void insert_wrapper(t_value *v, int backend) {
insert_functions[backend](v);
}
Besides, the different functions for one backend should be stuffed into a struct and you should create an array of such structs instead of one array per wrapper function.
You can use a simple version such as:
struct backend {
int (*insert)(...);
int (*remove)(...);
...
};
static struct backend db_backend = { db_insert, db_remove, ... };
static struct backend other_backend = { other_insert, other_remove, ... };
const struct backend *get_backend(enum backend_type type)
{
switch (type)
{
case DB_BACKEND:
return &db_backend;
case DB_OTHER:
return &db_other;
...
}
}
All of the above can be hidden inside a C file, with get_backend and the enumeration being public. Then you can use it like this:
struct backend *b = get_backend(DB_BACKEND);
b->insert(...);
b->remove(...);
Many details are missing, of course (many people like using typedef, for example). This is a basic setup, you can also create wrapper functions if you don't like the b->insert(...) syntax or if you want to set the back end once and then use insert() and remove() in the code. This is also useful if you already have some code that calls insert() directly and you want to direct the call to the right back end.
If you want a more elaborate solution, have a look at http://www.cs.rit.edu/~ats/books/ooc.pdf. You don't have to implement every last detail from it, but it can give you a few ideas.

How do I mock objects without inheritance (in C)?

We use a simple object model for our low level networking code at work where struct pointers are passed around to functions which are pretending to be methods. I've inherited most of this code which was written by consultants with passable C/C++ experience at best and I've spent many late nights trying to refactor code into something that would resemble a reasonable structure.
Now I would like to bring the code under unit testing but considering the object model we have chosen I have no idea how to mock objects. See the example below:
Sample header (foo.h):
#ifndef FOO_H_
#define FOO_H_
typedef struct Foo_s* Foo;
Foo foo_create(TcpSocket tcp_socket);
void foo_destroy(Foo foo);
int foo_transmit_command(Foo foo, enum Command command);
#endif /* FOO_H_ */
Sample source (foo.c):
struct Foo_s {
TcpSocket tcp_socket;
};
Foo foo_create(TcpSocket tcp_socket)
{
Foo foo = NULL;
assert(tcp_socket != NULL);
foo = malloc(sizeof(struct Foo_s));
if (foo == NULL) {
goto fail;
}
memset(foo, 0UL, sizeof(struct Foo_s));
foo->tcp_socket = tcp_socket;
return foo;
fail:
foo_destroy(foo);
return NULL;
}
void foo_destroy(Foo foo)
{
if (foo != NULL) {
tcp_socket_destroy(foo->tcp_socket);
memset(foo, 0UL, sizeof(struct Foo_s));
free(foo);
}
}
int foo_transmit_command(Foo foo, enum Command command)
{
size_t len = 0;
struct FooCommandPacket foo_command_packet = {0};
assert(foo != NULL);
assert((Command_MIN <= command) && (command <= Command_MAX));
/* Serialize command into foo_command_packet struct */
...
len = tcp_socket_send(foo->tcp_socket, &foo_command_packet, sizeof(foo_command_packet));
if (len < sizeof(foo_command_packet)) {
return -1;
}
return 0;
}
In the example above I would like to mock the TcpSocket object so that I can bring "foo_transmit_command" under unit testing but I'm not sure how to go about this without inheritance. I don't really want to redesign the code to use vtables unless I really have to. Maybe there is a better approach to this than mocking?
My testing experience comes mainly from C++ and I'm a bit afraid that I might have painted myself into a corner here. I would highly appreciate any recommendations from more experienced testers.
Edit:
Like Richard Quirk pointed out it is really the call to "tcp_socket_send" that I want to override and I would prefer to do it without removing the real tcp_socket_send symbol from the library when linking the test since it is called by other tests in the same binary.
I'm starting to think that there is no obvious solution to this problem..
You can use macro to redefine tcp_socket_send to tcp_socket_send_moc and link with real tcp_socket_send and dummy implementation for tcp_socket_send_moc.
you will need to carefully select the proper place for :
#define tcp_socket_send tcp_socket_send_moc
Have a look at TestDept:
http://code.google.com/p/test-dept/
It is an open source project that aims at providing possiblity to have alternative implementations, e.g. stubs, of functions and being able to change in run-time which implementation of said function to use.
It is all accomplished by mangling object files which is very nicely described on the home page of the project.
Alternatively, you can use TestApe TestApe Unit testing for embedded software - It can do it, but note it is C only.
It would go like this -->
int mock_foo_transmit_command(Foo foo, enum Command command) {
VALIDATE(foo, a);
VALIDATE(command, b);
}
void test(void) {
EXPECT_VALIDATE(foo_transmit_command, mock_foo_transmit_command);
foo_transmit_command(a, b);
}
Not sure what you want to achieve.
You can add all foo_* functions as function pointer members to struct Foo_s but you still need to explicitly pass pointer to your object as there is no implicit this in C. But it will give you encapsulation and polymorphism.
What OS are you using? I believe you could do an override with LD_PRELOAD on GNU/Linux: This slide looks useful.
Use Macro to refine tcp_socket_send is good. But the mock only returns one behavior. Or you need implement some variable in the mock function and setup it differently before each test case.
Another way is to change tcp_socket_send to function point. And points it to different mock function for different test case.
To add to Ilya's answer. You can do this.
#define tcp_socket_send tcp_socket_send_moc
#include "your_source_code.c"
int tcp_socket_send_moc(...)
{ ... }
I use the technique of including the source file into the unit testing module to minimize modifications in the source file when creating unit tests.

Resources