Disabling "incompatible pointer type" warning.

P

PraZ

Hi all.

Here is a simple code, which when compiled with gcc results in the
warning "incompatible pointer type" for arg 1, as expected. But this is
just what I want to do, because it makes it easy for me to handle the
single dimensional stream I have as a multidimensional array inside the
function func(). Now, I am just wondering if there is a way by which I
can disable this incompatible pointer type warning in gcc. Any
suggestions?

Best regards,
Prasanna.

/*The Code*/
#include <stdio.h>

void func(char [2][2]);

int main()
{
char* src;
int i;

src = (char*)malloc(16);

for (i=0; i<16; i++)
src = i;

func(src+4);

return 1;
}

void func(char src[2][2])
{
int r, c;

for (r = 0; r < 2; r++)
{
for (c = 0; c < 2; c++)
{
printf("%d, ", src[r][c]);
}
printf("\n");
}
}
 
B

Bob Hairgrove

Hi all.

Here is a simple code, which when compiled with gcc results in the
warning "incompatible pointer type" for arg 1, as expected. But this is
just what I want to do, because it makes it easy for me to handle the
single dimensional stream I have as a multidimensional array inside the
function func(). Now, I am just wondering if there is a way by which I
can disable this incompatible pointer type warning in gcc. Any
suggestions?

Best regards,
Prasanna.

/*The Code*/
#include <stdio.h>

void func(char [2][2]);

int main()
{
char* src;
int i;

src = (char*)malloc(16);

for (i=0; i<16; i++)
src = i;

func(src+4);

return 1;
}

void func(char src[2][2])
{
int r, c;

for (r = 0; r < 2; r++)
{
for (c = 0; c < 2; c++)
{
printf("%d, ", src[r][c]);
}
printf("\n");
}
}


A cast is necessary:
func((char (*)[2])src+4);

But why do you need to do it this way? Also, you leak memory in main.
And it's not C++ code if you are using malloc and free.
 
I

Ivan Vecerina

: Here is a simple code, which when compiled with gcc results in the
: warning "incompatible pointer type" for arg 1, as expected. But this is
: just what I want to do, because it makes it easy for me to handle the
: single dimensional stream I have as a multidimensional array inside the
: function func(). Now, I am just wondering if there is a way by which I
: can disable this incompatible pointer type warning in gcc. Any
: suggestions?
....
: void func(char [2][2]);
....
: char* src;
....
: func(src+4);

You can explicitly cast the parameter to the appropriate type:
func( (char(*)[2]) (src+4) );

But to me, it looks like func() might well be inapropriately
exposing implementation details in its interface.
If any 4-char sequence is acceptable as an input, the interface
should not expose a [2][2] bidimensional array to its callers.

If it is really useful for the implementation, func() could
create a local variable of the desired type:
void func( char const src[4] ) // include const if not modified
{
char (*tab)[2] = (char(*)[2])src;
...use tab as needed...
}


Regards -Ivan
 
M

Me

PraZ said:
Here is a simple code, which when compiled with gcc results in the
warning "incompatible pointer type" for arg 1, as expected. But this is
just what I want to do, because it makes it easy for me to handle the
single dimensional stream I have as a multidimensional array inside the
function func(). Now, I am just wondering if there is a way by which I
can disable this incompatible pointer type warning in gcc. Any
suggestions?

void func(char src[2][2])
{
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
printf("%d, ", src[r][c]);
}
printf("\n");
}
}

char *src = (char*)malloc(16);
func(src+4);

Working with multidimentional arrays in C/C++ really sucks and it's
made worse by the fact that doing a cast like what people in this
thread suggest leads to undefined behavior due to aliasing. The most
flexible and least annoying way to work with multidimentional arrays is
to just bite the bullet and do it yourself:

void func(T *arr, size_t width, size_t height, size_t pitch)
{
for (size_t h = 0; h < height; ++h) {
for (size_t w = 0; w < width; ++w) {
do_stuff(arr[w]);
}
arr += pitch;
}
}

Or a few variations:
- you can get rid of pitch and just use the width, I don't recommend
this because it's extremely useful for handling smaller slices of a
larger matrix.
- you can make the pitch variable signed (like ptrdiff_t) so you can
pass it negative values for it to travel upwards instead of downwards.
I don't really like this but I have seen people use it when working
with bitmaps with the y-axis pointing the opposite direction than what
they were expecting.
 
R

Rolf Magnus

PraZ said:
Hi all.

Here is a simple code, which when compiled with gcc results in the
warning "incompatible pointer type" for arg 1, as expected. But this is
just what I want to do, because it makes it easy for me to handle the
single dimensional stream I have as a multidimensional array inside the
function func(). Now, I am just wondering if there is a way by which I
can disable this incompatible pointer type warning in gcc.

By writing correct code?
Any suggestions?

Best regards,
Prasanna.

/*The Code*/
#include <stdio.h>

void func(char [2][2]);

This is equivalent to:

void func(char (*)[2]);

i.e. a function that takes a pointer to an array of 2 chars.
int main()
{
char* src;
int i;

src = (char*)malloc(16);

Don't use malloc. Use new[].

Btw: you forgot to #include the header that contains the declaration for
malloc(): stdlib.h
for (i=0; i<16; i++)
src = i;

func(src+4);


Your dynamically allocated memory is never freed.
return 1;

Why 1? Standard C++ defines three possible return values, which are 0,
EXIT_SUCCESS (being equivalent to 0) and EXIT_FAILURE. Most systems support
more than that, but typically, anything except 0 means failure.

I'd probably do:

int main()
{
char (*src)[2] = new char[8][2];

for (int i=0; i<8; i++)
{
src[0] = i*2;
src[1] = i*2+1;
}

func(src+2);

delete [] src;

return 0;
}
void func(char src[2][2])
{
int r, c;

for (r = 0; r < 2; r++)
{
for (c = 0; c < 2; c++)
{
printf("%d, ", src[r][c]);
}
printf("\n");
}
}
 
F

Fei Liu

Me said:
Working with multidimentional arrays in C/C++ really sucks and it's
made worse by the fact that doing a cast like what people in this
thread suggest leads to undefined behavior due to aliasing. The most
flexible and least annoying way to work with multidimentional arrays is
to just bite the bullet and do it yourself:

void func(T *arr, size_t width, size_t height, size_t pitch)
{
for (size_t h = 0; h < height; ++h) {
for (size_t w = 0; w < width; ++w) {
do_stuff(arr[w]);
}
arr += pitch;
}
}

Or a few variations:
- you can get rid of pitch and just use the width, I don't recommend
this because it's extremely useful for handling smaller slices of a
larger matrix.
- you can make the pitch variable signed (like ptrdiff_t) so you can
pass it negative values for it to travel upwards instead of downwards.
I don't really like this but I have seen people use it when working
with bitmaps with the y-axis pointing the opposite direction than what
they were expecting.

Use std::valarray, boost::multiarray, blitz::array. These implementations
all support multi dimensional arrays.
 
G

Gernot Frisch

Why 1? Standard C++ defines three possible return values, which are
0,
EXIT_SUCCESS (being equivalent to 0) and EXIT_FAILURE. Most systems
support
more than that, but typically, anything except 0 means failure.

Because of the memory leak? ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top