![]() |
Incompatible pointer type (double pointer in a function)
I have a simple function like:
:
In the main part of the program, I have: :
but I get the following message from gcc: :
twopts.c:158: warning: passing argument 2 of ‘H2’ from incompatible pointer typeIs it possible to call function H2 giving a statically allocated variable as argument? I mean... without copying a lot of objects. I know, I know... in function H2 the matrix is 4x4, so it wouldn't be necessary to use a pointer like that. But I just used that function as an example. I have other similar functions where I don't know the dimensions a priori. Glad if anyone can help! Thank you in advance, Gabriel. |
Re: Incompatible pointer type (double pointer in a function)
Forgot to mention... despite this being just a warning message, when I run the program I get a segmentation fault.
See you! |
Re: Incompatible pointer type (double pointer in a function)
The standard requires that the compiler have a means of converting the name of an array into a pointer to that array. Now, the question is, is that a pointer or a double pointer or a triple pointer? You could coerce that with a cast, and the compiler would accept that you knew what you were doing.
Obviously, though, you don't. If you consider a contiguous array of 16 doubles, that could be a 4x4 array or a 2x8 array or a 1x16 array or a 16x1 array or.... The address of that array does not convey that information. How do you expect the compiler to resolve (and build into H2) a reference like H[1][2] when that could be the fifth item in the array (second row, third element of a 4x4) or the ninth item in the array (second row, third element of a 2x8) or whatever? If you want the compiler to handle it, give the compiler the information. Pass sizes if they're variable, or define H2 so that it knows the size in advance. Voodoo isn't going to work, even if you have a bunch of dead chickens. |
Re: Incompatible pointer type (double pointer in a function)
Thank you for your response. I'm not a professional programmer... Hope you can respect that.
|
Re: Incompatible pointer type (double pointer in a function)
Certainly. As a non-professional programmer working on a solution to a problem, you might want to consider a language that affords a greater level of abstraction than C or C++. When you mess with C/C++ you're often under the hood, even though you're not into the carburetor.
You might want to consider something like Python (or others), which are more abstract and less-strongly-typed languages. |
Re: Incompatible pointer type (double pointer in a function)
Thank you again. That is some piece of advice I will consider.
|
Re: Incompatible pointer type (double pointer in a function)
Dear DaWei,
This is the last time I will bother you (or anyone else who wants to reply, please). Using a cast, I managed to do the code work. It looks like: :
Is there a way I can use the cast (double**)? I think it will be easier applying it to my other functions. Maybe I can explain better the problem. I have a set of functions that take matrices as arguments. Sometimes, these matrices will have been allocated statically; sometimes dynamically. I want to make these functions as generic as possible, in the sense that they accept every kind of matrix and I do the least dynamic allocation. To do that, I have to use: :
If I can understand how to use casts with (double**), I believe the problem will be solved. I tried a few times but no success. Any help will be valuable. Cheers, Gabriel. |
Re: Incompatible pointer type (double pointer in a function)
This is a multifaceted problem. Until you get it all visualized in your head, you're going to have a mess, regardless of how you try to pass a reference to your matrix.
If you define an array as double myArray [16]; you will get precisely the same memory structure as if you defined doubly myMatrix [4][4];.If you obtain the address of any of those elements, in whatever fashion, you have a pointer to a double. A double** is not a pointer to a double, it is a pointer to a pointer to a double. Let's say you want to treat that memory as a 4x4 matrix and you want to point at element [1][3]. Your pointer is going to have to be derived, somehow, by taking the initial address, adding the row number TIMES THE LENGTH OF A ROW, and then adding the column number. In this case, that would be 1*4 + 3, or 7. Since array indexes are zero based, that would point you to the 4th element in the 2nd row, which is the 8th sequential element in the set of elements. If you wanted to treat it as a 2x8 matrix and you wanted to address element [1][3], that would be 1*8 + 3, element 11, the 12th sequential element. You can see that finding [1][3] requires arithmetic that is governed by the dimensions envisioned. You have to either give these dimensions to the processing function, or you have to design the parameters in such a way that the compiler can infer the dimensions. Now, suppose that you decided to make your 4x4 matrix by allocating 4 SEPARATE 4-element arrays. You'd need a separate 4 element array that held, not doubles, but double pointers. Each of these 4 pointers would point to one of the rows. If you wanted to access the first row, you would need to get the first double-pointer. You can access that with a pointer TO a double pointer. If you increment the double**, it will point to the second double pointer. That pointer, when dereferenced, would point to the second array of doubles, the second row of the matrix. If you aren't seeing the differences and implications of these approaches, you are going to have a very tough time making a generic function that will deal with multidimensional arrays allocated in different ways under different circumstances. It is not trivial. You are going to sweat and bleed and debug your ass off. |
Re: Incompatible pointer type (double pointer in a function)
In order to make this work, the function will have to know the size of the arrays. Otherwise, you will get a segmentation fault, because it will keep trying to read past the end of the array.
For your case, this should work: :
void H2(double r, double H[4][4] ) {Alternatively, this could work: :
void H2(double r, double H[][4] ) {You could abuse your compiler and do something like this if it works: :
void H2(double r, double *H ) {I don't know how your formulas work, but this is basically the solution for general purpose (although you can manually inline the extra function): :
void H2(double r, double *H, int rows, int cols )I hope this helped you understand what you need to do rather than given you code to cut and paste, because if you just wanted code to c&p, I would have done a better job. : ) |
Re: Incompatible pointer type (double pointer in a function)
I'll try to answer both posts at once.
Yes, DaWei, I understand the issues of this problem. I had the program working, but using mostly dynamic allocation. Thus, If I allocated a matrix with double **H in the main part of the program and then passed it to function H2, I think (as you said) the compiler assumed I knew what I was doing. When I changed the allocation to double H[4][4], I thought the compiler would still understand that. With other languages, that's what would happen.I wanted, if possible, to change my functions as little as possible, but I understand I'll have to do some pointer arithmetic. No problem with that :S. Harakim, thank you for your ideas. The first two work in this case, but are not general enough for the rest of the code. Yes, the third works in gcc... I was just trying to avoid it (for portability purposes). I know the code can (must) be changed. I won't, for example, calculate r*(1-r) so many times (several elements of the matrix are exactly the same). I'll also use logarithms to work with sums rather than multiplications (r can be really small).Overall, now I understand the path to follow. All your ideas were most valuable! As a plant breeder, I have some trouble with programming in C... But my code is for an iterative process that can run for quite some time, so I need it to be fast. Regards, Gabriel. |
| All times are GMT -5. The time now is 3:18 AM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC