问题
I'm trying to compile a C codebase as C++, tweaking some of the includes. It uses strchr()
on unsigned char pointers, e.g.:
#include <string.h>
#include <stdio.h>
// Cannot modify this file with any non-C-isms, but let's say an include can
// be changed (although all things being equal I'd rather not)
#include <SomethingICanChange.h>
int main(int argc, char* argv[]) {
unsigned char b = 'B';
unsigned char const * str = "ABC";
unsigned char const * pos = strchr(str, b);
if (pos) {
printf("position is %d\n", pos - str);
}
return 0;
}
That causes an error in C++ (for reasons explained elsewhere)...even with -fpermissive
.
test.c: In function ‘int main(int, char**)’:
test.c:6:33: warning: invalid conversion from ‘const char*’ to ‘const unsigned char*’ [-fpermissive]
test.c:7:46: error: call of overloaded ‘strchr(const unsigned char*&, unsigned char&)’ is ambiguous
test.c:7:46: note: candidates are:
In file included from test.c:1:0:
/usr/include/string.h:215:14: note: char* strchr(char*, int) <near match>
/usr/include/string.h:215:14: note: no known conversion for argument 1 from ‘const unsigned char*’ to ‘char*’
/usr/include/string.h:217:22: note: const char* strchr(const char*, int) <near match>
/usr/include/string.h:217:22: note: no known conversion for argument 1 from ‘const unsigned char*’ to ‘const char*’
Usually when faced with this kind of thing I go "strchr, yuck, just get rid of it entirely". But I don't want to modify these files myself, and this is C code that is being kept very portable to rather old platforms. They wouldn't be happy putting casts at callsites to appease C++...though if a "struchr" existed and was standard they'd probably use it.
I can also hack around it one way or another, like in SomethingICanChange.h
I could add:
unsigned char const * strchr(unsigned char const * s, int c) {
return (unsigned char const *)strchr((char const *)s, c);
}
That works with -fpermissive
. But I wouldn't be able to check that overload into the C codebase (well, without an #ifdef). Just wondering if anyone has a better idea, I will pitch adding struchr
if that's what people in this situation wind up doing (or whatever name is common if there's a common one).
回答1:
Initial note: I am aware that this is also quite an ugly thing to do, but it might help you with a (hopefully) better idea!
How about using a macro:
#define strchr(s, c) ((unsigned char const *)strchr((char const *)s, c))
You could include it as a compile flag (-D) from you Makefile/build script. I suppose you have a custom Makefile/build script for your C++ project, so you do not need to add this macro to the C code-base.
To make it slightly better, you can use an additional file, that you include from your Makefile/build script, which adds these macros in a (more) structured way to CPPFLAGS
来源:https://stackoverflow.com/questions/13906150/minimally-invasive-change-for-strchr-on-unsigned-char-in-c-from-a-c-codebase