I have the following code which compiles without warnings in VS2015 (all warnings enabled):
// buffer.h
typedef struct {
char * const start; // start of the buffer
char * const end; // one byte after the end of the buffer
char * pos; // current position
} Buffer;
static inline Buffer Buffer_create(char *buffer, int size) {
Buffer b;
char ** const startPtr = &((char *)b.start);
char ** const endPtr = &((char *)b.end);
*startPtr = buffer;
*endPtr = buffer + size;
b.pos = buffer;
return b;
}
Since .start
and .end
members are const
, I am doing the casting thingy to avoid getting compile warnings, and the code indeed compiles without warnings and works without issues.
However, if I want to test this using gtest, and if I want to reference this file from a .cpp file:
// some_file.cpp
extern "C" {
#include "buffer.h"
}
I get the the C4190 warning from Visual Studio, described as:
'Buffer_create' has C-linkage specified, but returns UDT 'Buffer' which is incompatible with C
But the UDT is clearly "compatible with C", since I can build it without warnings until I try to reference it from a cpp file.
If I remove const
from the struct
definition, the warning goes away.
So, it seems like MSVC thinks char * const
is not "compatible with C". Am I doing something illegal, or is this a compiler bug?
According to the documentation you linked for warning C4190, it is not supported to have a function which returns a struct
by value, called from both C and C++.
(In the C++ Standard most of the details of language-mixing are given as implementation-defined, and in this case MSVC complies by documenting that this is not supported).
I also would not recommend having an inline
function in a header that is compiled as both C and C++, because the semantics of inline
differs between the two languages so it is asking for trouble.
You will have to make a major design change to avoid this problem, if you want to use Buffer_create
from both languages. For example, "return" the result via a pointer out-parameter, and do away with the const
struct members.