views:

200

answers:

6

I've a question for a warning message that i get. For this line,using qsort library function:

qsort(catalog, MAX ,sizeof catalog, struct_cmp_by_amount); 

I get this warning:

warning: passing argument 4 of ‘qsort’ makes pointer from integer without a cast

EDIT:

struct_cmp_by_amount is the following function on the program.(--->) catalog is a struct and MAX is defined as 100

BUT,for another program with the same code, with the same exactly struct_cmp_by_amount function, i dont get that warning for the 4th argument!

EDIT: I've also have to say that on both programs i havent used prototypes of functions! But for the 2nd program it works normally in contrast to the 1st one.

qsort(structs, structs_len, sizeof(struct st_ex), struct_cmp_by_amount);

EDIT:

st_ex is a struct

struct st_ex structs[]={./*elements*/..}

size_t structs_len = sizeof(structs) / sizeof(struct st_ex);

int struct_cmp_by_amount(const void *a, const void *b)
{
    struct catalogue *ia = (struct catalogue *)a;
    struct catalogue *ib = (struct catalogue *)b;
    return (int)(100.f*ia->amount - 100.f*ib->amount);  
}

I'm wandering about why that's happening. Have you any ideas?

A: 

Without knowing the types of the operands, then we can't resolve your type error.

DeadMG
@DeadMG .sorry! It's fixed now!
FILIaS
+5  A: 

I'm guessing, since I can't see your code.

qsort() takes the array to be sorted, the number of entries, the sizeof an entry, and a pointer to a comparison routine that takes two pointers to entries and compares them. (I don't remember the return type of the function, or the convention.)

It looks as though the compiler can't see a function declaration or function prototype for your comparision routine, struct_cmp_by_amount, is therefore presuming that it is an int (according to C rules), and is warning you that it needs a pointer (to a function) in that parameter position.

John R. Strohm
This sounds about right. If the function pointer is in scope but the signature is off, the compiler will complain about that being "incompatible". If it's not even in scope, it will be implicitly treated as `int`, as @John R. Strohm says.
Phil
What you are saying is right,but why does it work on the 2nd example? Both times i didnt use prototypes!
FILIaS
@FILIaS: Possibly the compiler figures it has warned you once, and it doesn't see a need to warn you twice.
John R. Strohm
@John R.Strohm. Is this possible? But how? in this 1st program i use this command twice and on both i get warning.
FILIaS
A: 

I assume you mean the qsort from the standard C library. The chances are that you have forgotten to include stdlib.h which declares the qsort function.

EDIT: Sorry, didn't read the error message properly. In fact, the other answer by John R. Strohm is probably right - you haven't got a declaration for the function that's visible to the compiler.

JeremyP
@JeremyP. library is included! declaration both on the 2 programs dont exist..but in ths view why is it working on the 2nd? I dont get there any warning!
FILIaS
+1  A: 

The prototype of struct_cmp_by_amount must be declared as

int struct_cmp_by_amount (const void* a, const void* b) {
  ...
}

to avoid the warning, even if you know a and b are some T*.

Also, make sure the forward declaration exists before calling qsort.

KennyTM
@KennyTM, when I pass in a pointer to a function using `const int *`, I get `warning: passing argument 4 of ‘qsort’ from incompatible pointer type ..... expected ‘__compar_fn_t’ but argument is of type ‘int (*)(const int *, const int *)’`. I think he just doesn't have it in scope.
Phil
@KennyTM. As u can see on the edited post the function is in this way declared. ok i understand what u mean about the calling of the function,but neither on the 2nd one exists but that one works regularly!
FILIaS
A: 

Is this line of code copied correctly?:

qsort(catalog, MAX ,sizeof catalog, struct_cmp_by_amount);

If so it should surely be:

qsort(catalog, MAX ,sizeof(*catalog), struct_cmp_by_amount);

Also your example of a working qsort line uses struct_cmp_by_price not struct_cmp_by_amount.

So as has been pointed out best check your declarations there and whether they are in scope. The facft that the compiler has cast struct_cmp_by_amount as integer suggests that it can't find a declaration for it.

ChrisBD
`sizeof` requires parentheses when applied to an actual type, but not when applied to an expression that has a type (and that includes single variables). Of course, giving an array, and saying that an element type is the same size as the array (perhaps this should be `sizeof *catalog`), is the wrong thing to do.
David Thornley
@David - I wasn't paying attention there sizeof(*catalog) is what I actually meant. I've had enough trouble with compilers complaining about paranthesis to put them in whether needed or not.
ChrisBD
but the warning is for the 4th argument! :/
FILIaS
+1  A: 

The problem appears to be that, in one case, the qsort() call can see the declaration of struct_cmp_by_amount(), and in the other it can't. Since you aren't using function prototypes, I'd guess that in one case the function declaration was before the qsort() call and in the other case afterwards.

Also, the first qsort() call listed could cause problems, since catalog is the pointer or array you're passing, and sizeof catalog is the size you're giving it. If catalog is an array here, you're saying that it's made of MAX things as big as the whole array, which means you'll be messing with far more memory than you've allocated, and potentially causing no end of bugs. If catalog is a pointer, you're saying that it's pointing to an array of items of pointer size. Neither seems plausible. Using sizeof *catalog or sizeof catalog[0] would make much more sense.

Also, using floating-point numbers to represent dollar amounts is prone to error; you're usually better off using an integer type to represent the number of cents. That's a different problem, though.

David Thornley
that's correct David. I didn't notice that..so many hours now....thnx
FILIaS