3

I have a very basic question.

What is wrong with this call?

int params[2] = {1, 1};
return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, &params);

The function is defined like this:

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c[])

{...

When I compile in XCode, I get the following warning:

warning: passing argument 4 of 'strcmp95' from incompatible pointer type

Sorry for being imprecise. Here is the function description:

/* Arguments: ying and yang are pointers to the 2 strings to be compared. The strings need not be NUL-terminated strings because the length is passed. y_length is the length of the strings. ind_c is an array that is used to define whether certain options should be activated. A nonzero value indicates the option is deactivated.
The options are: ind_c[0] Increase the probability of a match when the number of matched characters is large. This option allows for a little more tolerance when the strings are large. It is not an appropriate test when comparing fixed length fields such as phone and social security numbers. ind_c[1] All lower case characters are converted to upper case prior to the comparison. Disabling this feature means that the lower
case string "code" will not be recognized as the same as the upper case string "CODE". Also, the adjustment for similar characters section only applies to uppercase characters. The suggested values are all zeros for character strings such as names. */

2
  • Are you saying this doesn't compile elsewhere? Ie this is xcode specific? Commented Jan 31, 2011 at 9:45
  • I didn't know, that is why I added the tag. Could have been something was missing in XCode. Commented Jan 31, 2011 at 9:55

5 Answers 5

4

params is an int [2], which decays to an int * when passed to a function, and functions that take int []s as parameters are really taking int *s behind the scenes. Unfortunately, &params is an int(*)[2], which is closer to an int * than the int ** (same as int *[] in a function parameter) you need.

Your best option is to change your function to:

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c)

And assume that the caller willl always pass an int[2]. Or you can explicitly ask for an int(*)[2] - a pointer to an array of 2 ints:

double  strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[2])

But this seems unnecessary to guarantee that two ints are passed, and if you need to account for the possibility of more than two ints in the array is unsuitable. A better way is:

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c, size_t len)

size_t is an unsigned integer type guaranteed to be able to hold the size of any object or any array index, and in this case the len parameter is the length of your array ((sizeof params / sizeof params[0]) if you want to be fancy/forward thinking, 2 if you don't). That's the safest route.

By the way, your y_length parameter should also be a size_t variable. long is signed, and I'd hate to have to handle a string of -1 length. Even if you use unsigned long, there's no guarantee that long will be sufficient to handle a system's sizes (or, conversely, that an errantly large long value will be too big for your system to handle and cause confusion).

Sign up to request clarification or add additional context in comments.

6 Comments

No, &params is not the same as params. The addresses that they hold are the same but &params has type int (*)[2].
I opted for int (*ind_c)[2]. The function is only ever gonna get called by myself, and only in one place. That is never gonna change. So that option seems very safe in this scenario.
@Jens - This is what happens when you stay up until 5 a.m. after saying "I'm going to go to bed early tonight and wake up at a reasonable hour." Fixing.
@Joseph - If you only call it in one place and have such specific array requirements, why is it a separate function?
It is a function that was written in 1994. And not by myself. I am only using it. :)
|
2

strcmp95 takes a pointer to pointer to int (int **), while you are passing it a pointer to an array of two ints (int (*)[2]).

You could modify strcmp95 so that its signature looks like this:

double  strcmp95(char *ying, char *yang, long y_length, int (*ind_c)[] );

The point here is that a pointer to an array (int (*x)[]) is not the same as an array of pointers (which is int *(x[]) and is the same as int *x[])

2 Comments

Uhm... okay. I'll try and figure out how to change that. :) What are the advantages / disadvantages of either approach?
@Joseph Tura: I updated the answer. int *x[] is an array of pointers, while you are passing a pointer to an array.
1

It's hard to know whether strcmp95 should take an array of ints like you're trying to pass, or it is meant to take an array of int pointers as the prototype requests. The former seems likely - if so, you should change...

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c[])

...to...

double  strcmp95(char *ying, char *yang, long y_length, int *ind_c)

...or, equivalently...

double  strcmp95(char *ying, char *yang, long y_length, int ind_c[])

Comments

1

Why are you passing &params, params would be suffice, as an array acts like a pointer.

return strcmp95((char*)buffer1, (char*)buffer2, (long)stringLength, params);

And secondly strcmp95 should now be expecting an array of ints, this will be fine:

double  strcmp95(char *ying, char *yang, long y_length, int ind_c[])

Comments

1

Also I think you are passing params ( which is an integer pointer in itself ) and the function strncmp95 is expecting pointer to an array of integers i.e int *ind_c[].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.