简体   繁体   中英

How do I tell gcc to relax its restrictions on typecasting when calling a C function from C++?

I'm trying to use Cmockery to mock C functions called from C++ code. Because the SUT is in C++, my tests need to be in C++.

When I use the Cmockery expect_string() macro like this:

expect_string(mock_function, url, "Foo");

I get:

my_tests.cpp: In function ‘void test_some_stuff(void**)’:
my_tests.cpp:72: error: invalid conversion from ‘void*’ to ‘const char*’
my_tests.cpp:72: error:   initializing argument 5 of ‘void _expect_string(const char*, const char*, const char*, int, const char*, int)’

I see in cmockery.h that expect_string is defined:

#define expect_string(function, parameter, string) \
    expect_string_count(function, parameter, string, 1)
#define expect_string_count(function, parameter, string, count) \
    _expect_string(#function, #parameter, __FILE__, __LINE__, (void*)string, \
                  count)

And here's the prototype for _expect_string (from cmockery.h):

void _expect_string(
    const char* const function, const char* const parameter,
    const char* const file, const int line, const char* string,
    const int count);

I believe the problem is that I'm compiling C code as C++, so the C++ compiler is objecting to (void*)string in the expect_string_count macro being passed as the const char* string parameter to the _expect_string() function.

I've already used extern "C" around the cmockery.h include in my_tests.cpp like this:

extern "C" {
#include <cmockery.h>
}

...in order to get around name-mangling problems. (See " How do I compile and link C++ code with compiled C code? ")

Is there a command-line option or some other means of telling g++ how to relax its restrictions on typecasting from my test's C++ code to the C function in cmockery.c?

This is the command I'm currently using to build my_tests.cpp:

g++ -m32 -I ../cmockery-0.1.2 -c my_tests.cpp -o $(obj_dir)/my_tests.o

I undersatand it's not your code, but it looks like the easier way is probably to fix cmockery.h by removing this cast to (void*) (may be putting some section active only for C++ using #ifdef __cplusplus ).

that could even be put in your code, just redefining the expect_string_count macro

#ifdef __cplusplus
#undef expect_string_count
#define expect_string_count(function, parameter, string, count) \
    _expect_string(#function, #parameter, __FILE__, __LINE__, string, \
              count)
#endif

I don't think there's an option for this at the compiler level. You might be able to work around this (I assume you want to avoid modifying the CMockery sources because of comments I've read in another of your questions) by having wrapper header for CMockery that does something like the following to make it play nicely in both C and C++:

#ifndef MY_CMOCKERY_H
#define MY_CMOCKERY_H

/*
    A wrapper for cmockery.h that makes it C++ friendly while keeping things
    the same for plain-old C
 */

#if __cplusplus
extern "C" {
#endif

#include "cmockery.h"

#if __cplusplus
}
#endif


#if __cplusplus
// fixup CMockery stuff that breaks in C++

#undef expect_string_count
#define expect_string_count(function, parameter, string, count) \
    _expect_string(#function, #parameter, __FILE__, __LINE__, (char*)string, \
                  count)

#endif


#endif  /* MY_CMOCKERY_H */

An additional benefit is that now you've got a place that you can put any other hacks/fixes for CMockery under C++ you come across (hopefully not too many of them).

If you're up for modifying the CMockery stuff that's probably where it really belongs - maybe the maintainers would accept your patch? (I dunno).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM