SSH This
SSH This

Reputation: 1929

Type-casting in C for standard function

I am working on a C project (still pretty new to C), and I am trying to remove all of the warnings when it's compiled.

The original coders of this project have made a type called dyn_char (dynamic char arr) and it's an unsigned char * type. Here's a copy of one of the warnings:

warning: argument #1 is incompatible with prototype: prototype: pointer to char : ".../stdio_iso.h", line 210 argument : pointer to unsigned char

They also use lots of standard string functions like strlen(); so the way that I have been removing these warnings is like this:

strlen((char *)myDynChar);

I can do this but some of the files have hundreds of these warnings. I could do a Find and Replace to search for strlen( and replace with strlen((char*), but is there a better way?

Is it possible to use a Macro to do something similar? Maybe something like this:

#define strlen(s) strlen((char *)s)

Firstly, would this work? Secondly, if so, is it a bad idea to do this?

Thanks!

Upvotes: 2

Views: 1222

Answers (3)

perreal
perreal

Reputation: 97948

You can define a function:

char *uctoc(unsigned char*p){ return (char*)(p); }

and do the search replace strstr(x with strstr(uctoc(x). At least you can have some type checking. Later you can convert uctoc to a macro for performance.

Upvotes: 1

AShelly
AShelly

Reputation: 35540

This may or may not work

strlen may be a macro in the system header, in which case you will get a warning about redefining a macro, and you won't get the functionality of the existing macro.

(The Visual Studio stdlib does many interesting things with macros in <string.h>. strcpy is defined this way:

__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1(char *, __RETURN_POLICY_DST, __EMPTY_DECLSPEC, strcpy, _Pre_cap_for_(_Source) _Post_z_, char, _Dest, _In_z_ const char *, _Source))

I wouldn't be surprised at all if #defining strcpy broke this)`

Search and replace may be your best option. Don't hide subtle differences like this behind macros - you will just pass your pain on to the next maintainer.

Instead of adding a cast to all the calls, you may want to change all the calls to dyn_strlen, which is a function you create that calls strlen with the appropriate cast.

Upvotes: 1

Dan Fego
Dan Fego

Reputation: 14004

This is an annoying problem, but here's my two cents on it.

First, if you can confidently change the type of dyn_char to just be char *, I would do that. Perhaps if you have a robust test program or something you can try it out and see if it still works?

If not, you have two choices as far as I can see: fix what's going into strlen(), or have your compiler ignore those warnings (or ignore them yourself)! I'm not one for ignoring warnings unless I have to, but as far as fixing what goes into strlen...

If your underlying type is unsigned char *, then casting what goes into strlen() is basically telling the compiler to assume that the argument, for the purposes of being passed to strlen(), is a char *. If strlen() is the only place this is causing an issue and you can't safely change the type, then I'd consider a search-and-replace to add in casts to be the preferable option. You could redefine strlen with a #define like you suggested (I just tried it out and it worked for me), but I would strongly recommend not doing this. If anything, I'd search-replace strlen() with USTRLEN() or something (a fake function name), and then use that as your casting macro. Overriding C library functions with your own names transparently is a maintainability nightmare!

Two points on that: first, you're using a different name. Second, you're using all-caps, as is the convention for defining such a macro.

Upvotes: 4

Related Questions