1

I have the following code:

/*
 * Pointer to a function that reads a codesegment
 */
typedef bool (*BRCS)(void *, uint32, uint64 *, uint64 *, const char **, const char **);
BRCS get_prog_id;

/*
 * 'get_prog_id' is loaded from a dynamic library
 */

uint64 start_o;
uint64 length_o;
char prog_id[256];
char err[256];

get_prog_id(NULL, 0, &start_o, &length_o, &prog_id, &err);

When I run my compiler, I get the following warnings:

passing argument 5 of get_prog_id from incompatible pointer type    
passing argument 6 of get_prog_id from incompatible pointer type    

So, it's complaining that I don't have char ** for my last two arguments.

I'm confused. My understanding was that the variable representing an array of TYPES is equivalent to a pointer to a TYPE. As such, applying the & operator would give you a pointer to a pointer to a TYPE.

What am I missing here?

Dancrumb
  • 26,597
  • 10
  • 74
  • 130

2 Answers2

2

There are two problems here:

(1)

The type of &prog_id is not char *, it's char (*)[256]; i.e. pointer-to-char-array-of-length-256.

(2)

Even if you could get a char ** (e.g. char *prog_id = malloc(256); &prog_id), char ** is not compatible with const char **, for somewhat obscure reasons. The best explanation if probably here: http://c-faq.com/ansi/constmismatch.html.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Yikes! That's some esoteric stuff. Thanks – Dancrumb Feb 09 '11 at 18:22
  • Thanks; I removed the array syntax and replaced it with an explicit point. I then cast `&prog_id` to `(const char **)`. The link you provided suggested that the cast may indicate other problems, but I believe that problem is with the library definition, so I'm stuck working round it – Dancrumb Feb 09 '11 at 21:03
  • @Dancrumb: The library definition is indicating that it expects you to define the variable as `const char *prog_id`. (Note that this doesn't mean that `prog_id` itself is `const` - just the characters that it points to). – caf Feb 09 '11 at 23:56
1

Pointer and array types are equivalent only up to a single level. Whenever another level of indirection comes into play, they cease to be the same.

Understanding this is easiest if you think about what pointer arithmetic is supposed to work like in such a case. Consider the following definitions:

typedef char tenchars[10];
tenchars *x;

Now, &(x[1]) (i.e. x+1) ought to mean “the address of x plus 10 chars”, right? But what if I do the following:

char **y = (char **)x;

What does &(y[1]) mean now and why?

Put differently: An array of pointers is not the same as an array of arrays. Hence, a pointer to a pointer is not the same as a pointer to an array.

Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47