A pointer to the type of the array or what happens to the "decay of the array into a pointer" when adding "typedef", "const", "*" and "&",

I have this opaque type type_tand function prototype, for example, foo(type_t *t)and the called one:

int bar(void)
{
    type_t t;

    foo(&t);

    return 0;
}

I wanted to change the function prototype from foo(type_t *t)to foo(const type_t *t).

Unfortunately, it is type_tdefined as an array, for example typedef char type_t[16]) ... Therefore, the calling function foowith an argument &tforces the compiler to generate a warning.

First, the function foomust have a prototype, such as foo(type_t t)called with foo(t). In this case, I was hoping that decomposing the array into a pointer rule would also allow foo(&t), but this does not apply to the operator &. Maybe it will work if fooit was writtenfoo(void *t)

Note: you can skip the detailed examples, see end

So, I wrote this little test program for reproducing warnings / errors https://gist.github.com/2644970

GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) generates these warnings:

array.c: In function β€˜test_array_pointer’:
array.c:36: warning: return makes integer from pointer without a cast
array.c: In function β€˜test_const_array_pointer’:
array.c:59: warning: return makes integer from pointer without a cast
array.c: In function β€˜main’:
array.c:132: warning: passing argument 1 of β€˜test_array_pointer’ from incompatible pointer type
array.c:18: note: expected β€˜uint8_t (*)[16]’ but argument is of type β€˜uint8_t *’
array.c:134: warning: passing argument 1 of β€˜test_const_array_pointer’ from incompatible pointer type
array.c:41: note: expected β€˜const uint8_t (*)[16]’ but argument is of type β€˜uint8_t (*)[16]’
array.c:135: warning: passing argument 1 of β€˜test_const_array_pointer’ from incompatible pointer type
array.c:41: note: expected β€˜const uint8_t (*)[16]’ but argument is of type β€˜uint8_t *’
array.c:137: warning: passing argument 1 of β€˜test_array’ from incompatible pointer type
array.c:64: note: expected β€˜uint8_t *’ but argument is of type β€˜uint8_t (*)[16]’
array.c:140: warning: passing argument 1 of β€˜test_const_array’ from incompatible pointer type
array.c:82: note: expected β€˜const uint8_t *’ but argument is of type β€˜uint8_t (*)[16]’
array.c:143: warning: passing argument 1 of β€˜test_const_pointer’ from incompatible pointer type
array.c:100: note: expected β€˜const uint8_t *’ but argument is of type β€˜uint8_t (*)[16]’

While LLVM / Clang version 1.1 (branch / release_27) creates those:

array.c:36:10: warning: incompatible pointer to integer conversion returning 'array_t' (aka 'uint8_t [16]'), expected 'uintptr_t' (aka 'unsigned int') [-pedantic]
  return a[0]; /* warning: return makes integer from pointer without a cast */
         ^~~~
array.c:59:10: warning: incompatible pointer to integer conversion returning 'array_t const' (aka 'uint8_t const[16]'), expected 'uintptr_t' (aka 'unsigned int') [-pedantic]
  return a[0]; /* warning: return makes integer from pointer without a cast */
     ^~~~
array.c:132:3: warning: incompatible pointer types passing 'array_t' (aka 'uint8_t [16]'), expected 'array_t *' [-pedantic]
  TEST(array_pointer, a);
  ^~~~~~~~~~~~~~~~~~~~~~
array.c:132:23: note: instantiated from:
  TEST(array_pointer, a);
                      ^
array.c:134:3: warning: incompatible pointer types passing 'array_t *', expected 'array_t const *' [-pedantic]
  TEST(const_array_pointer, &a);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
array.c:134:29: note: instantiated from:
  TEST(const_array_pointer, &a);
                            ^~
array.c:135:3: warning: incompatible pointer types passing 'array_t' (aka 'uint8_t [16]'), expected 'array_t const *' [-pedantic]
  TEST(const_array_pointer, a);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
array.c:135:29: note: instantiated from:
  TEST(const_array_pointer, a);
                            ^
array.c:137:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t *' [-pedantic]
  TEST(array, &a);
  ^~~~~~~~~~~~~~~
array.c:137:15: note: instantiated from:
  TEST(array, &a);
              ^~
array.c:140:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t const *' [-pedantic]
  TEST(const_array, &a);
  ^~~~~~~~~~~~~~~~~~~~~
array.c:140:21: note: instantiated from:
  TEST(const_array, &a);
                    ^~
array.c:143:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t const *' [-pedantic]
  TEST(const_pointer, &a);
  ^~~~~~~~~~~~~~~~~~~~~~~
array.c:143:23: note: instantiated from:
  TEST(const_pointer, &a);
                      ^~
8 diagnostics generated.

note: abridged version

See the last example:

typedef char array_t[16];

static int
test_const_array_pointer(const array_t *a)
{
    return 0;
}

int
main(void)
{
    array_t a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };
    const array_t b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };

    test_const_array_pointer(&a); /* warning: passing argument 1 of β€˜test_const_array_pointer’ from incompatible pointer type
                                     note: expected β€˜const char (*)[16]’ but argument is of type β€˜char (*)[16]’ */

    test_const_array_pointer(a); /* warning: passing argument 1 of β€˜test_const_array_pointer’ from incompatible pointer type
                                     note: expected β€˜const char (*)[16]’ but argument is of type β€˜char *’ */

    test_const_array_pointer(&b); /* OK */

    test_const_array_pointer(b); /* warning: passing argument 1 of β€˜test_const_array_pointer’ from incompatible pointer type
                                    note: expected β€˜const char (*)[16]’ but argument is of type β€˜const char *’ */

    return 0;
}

, a & b. , , foo(const char *), const char *, . char *.

, , , const array_t *, const? ( 11 ).

+3
1

, C. , (, const) - , . , , . , const array_t *, , const. , .

, test_const_array_pointer(&a) . C , . 6.5.16.1 :

, ( , lvalue) , - , ;

const, - . , " " "array of const chars" , .

, " char ** , const char * const *". , , ( , ), , - const . , / , .

+3

All Articles