0
votes

I'm trying to make some code MISRA complaint and I have the following piece of code:

static void DBusCallback(GObject *object, GAsyncResult *res, gpointer user_data) {
    std::string * const tmp = reinterpret_cast<std::string*>(user_data);
    ...

where DBusCallback is a callback for call_DBus:

   (void)call_DBus(proxy, NULL, &DBusCallback, reinterpret_cast<void*>(new std::string(user_data)));

//last pram is the user_data from the callback

It compiles and runs ok, but I have the following MISRA warning at string conversion from gpointer: MISRA.CAST.PTR.UNRELATED : Object of pointer type 'gpointer' cast to unrelated type 'string*'

The rule is: MISRA-C++ Rule 5-2-7 (required): An object with pointer type shall not be converted to an unrelated pointer type, either directly or indirectly. [Unspecified 5.2.10(7)] Rationale The result of converting from a pointer to an unrelated type is unspecified.

Any idea to avoid this warning?

2
Are you sure it works fine? What is gpointer? I can't see how it could work unless it is a pointer to std::string.juanchopanza
Yes, it works. I create new std::string, that is cast to void*, then in the callback is converted again to std::string. Gpointer is: typedef void* gpointer;user3458705
Well, MISRA is designed to stop you from doing things like that. So the best way to get rid of the warning is to ensure that you have the same, correct, type all the way. Besides, MISRA prohibits function pointers as well, so you can't do &DBusCallback either...Lindydancer
@user3458705 it works in your particular implementation, but that's not guaranteed on another compiler or even a new version of yours. That's what unspecified means, but if you don't want to take Lindydancer's advice you'll need need to create a deviation and document your rationale.Veriloud

2 Answers

0
votes

reinterpret_cast<> is in general not MISRA friendly.

MISRA wants to make sure the conversion is possible and no runtime error will come from this conversion. So, you need a function to perform the conversion in a secure way what will probably make you create another class or function that gets a gpointer and returns a string.

Another option (if possible) is that at this level (so near of the hardware) you could disable reinterpret_cast<> warnings for the functions accessing it.

The last one is forgetting about std::string and using const char*:

static void DBusCallback(GObject *object, GAsyncResult *res, gpointer user_data) {
    std::string * const tmp = reinterpret_cast<std::string*>(user_data);

   (void)call_DBus(proxy, NULL, &DBusCallback, reinterpret_cast<const char*>(user_data));

Btw, I supose you are deleting or managing the memory of the std::string*, if not, you will lack memory.

-1
votes

Try to use static_cast instead of reinterpret_cast on the gpointer. I didn't get the warning, in my case it was a different class and not string but I don't think this is relevant, like this:

std::string * tmp = static_cast<std::string *>(user_data);