a warning I have not understood yet

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody.

 

int main()
{
    char array[2];
    array[0]='A';
    array[1]='b';
    
    char*p;
    p=array;
    
    for(int i=0;i<2;i++)
    {
        printf("%c\n",*p);
        p++;
    }
    
    return 0;
}

 

when I write a code like above for normal pc (in GCC) there is no warning. But, when I compile it in avrgcc there is a warning 'incompatible pointer type'. what is that? Any idea?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What line is it complaining about?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 p=array;

this line.

and tahn I edited p=&array[0] and there is no warning.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is that the exact code that you are compiling?

 

ie, copied direct from the source file, and pasted into the forum - with no manual re-typing?

 

What compiler version?

 

Do you also get any other errors and/or warnings?

 

Please post the full error message - again, copy & paste.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well apart from anything else the code is not complete as it misses the #include <stdio.h>. Anyway....

C:\SysGCC\avr\bin>type avr.c
#include <stdio.h>

int main()
{
    char array[2];
    array[0]='A';
    array[1]='b';

    char*p;
    p=array;

    for(int i=0;i<2;i++)
    {
        printf("%c\n",*p);
        p++;
    }

    return 0;
}
C:\SysGCC\avr\bin>avr-gcc -Wall -mmcu=atmega16 -Os avr.c -o avr.elf

C:\SysGCC\avr\bin>

Even with -Wall I cannot get a warning out of avr-gcc about this so I would like to hear more about the environment in which this is built and the command lines used etc.

 

Of course I *can* get it to behave similar to what the OP suggests:

C:\SysGCC\avr\bin>avr-gcc -mmcu=atmega16 -Os avr.c -o avr.elf
avr.c: In function 'main':
avr.c:10:6: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     p=array;
      ^
avr.c:14:23: error: invalid type argument of unary '*' (have 'int')
         printf("%c\n",*p);
                       ^

The way I achieved that was simply to change:

    char*p;

to be

    char p;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

C:\SysGCC\avr\bin>avr-gcc -Wall -mmcu=atmega16 -Os avr.c -o avr.elf

What version is that?

 

I get:

mesuttopuzlu.c: In function 'main':
mesuttopuzlu.c:12:5: error: 'for' loop initial declarations are only allowed in C99 or C11 mode
     for(int i=0;i<2;i++)
     ^
mesuttopuzlu.c:12:5: note: use option -std=c99, -std=gnu99, -std=c11 or -std=gnu11 to compile your code

With

AVR-GCC.exe (AVR_8_bit_GNU_Toolchain_3.5.3_1700) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

But adding the -std=c99 does, indeed, compile with no warnings & no errors

 

 

If I simply change:

    char array[2];

to be

    char *array[2];

 

Then I get:

mesuttopuzlu.c: In function 'main':
mesuttopuzlu.c:6:13: warning: assignment makes pointer from integer without a cast
     array[0]='A';
             ^
mesuttopuzlu.c:7:13: warning: assignment makes pointer from integer without a cast
     array[1]='b';
             ^
mesuttopuzlu.c:10:6: warning: assignment from incompatible pointer type
     p=array;
      ^

 

Bingo!

 

cheeky

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
What version is that?
5.4.0 (from FSF not Atmel)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, thanks - I guess that must default to a later 'C' standard, then?

 

Anyhow, it seems clear that the code the OP posted is not the actual code that causes the reported "problem".

 

<rolls eyes>

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will be corrected if I am wrong, but it might be that:

 

>>char array[2];

 

this is actually is telling the compiler/linker  to reserve a number of bytes in the ram area.

so it is not actually a location

 

>>p=array;

this tells that the pointer has to point to the location 'array' but that in fact is not a single location, but in your case at least 2. To what location should the pointer point then? the first or the second

 

with changing it to

>>p=&array[0]

you are actually telling the pointer should be the adress (&)  of location 0 in the reserved memory space, and thus is a valid assignment

 

at least that is the way I like to remember the pointer stuff as it makes life easy, but if you are not working with it on a daily basis hard to grasp.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
I will be corrected if I am wrong

I'm afraid you are wrong.

 

Remember that the code as shows in the OP does compile correctly without any warnings. The only reason Cliff & I were making changes was to try to reproduce the warning that the OP had hinted at; in other words, we were deliberately introducing errors.

 

>>char array[2];

this is actually is telling the compiler/linker  to reserve a number of bytes in the ram area.

Correct.

 

so it is not actually a location

Not correct.

The name of an array is, effectively, a pointer to the start of the first element; ie, it gives the address of the 1st element.

 

>>p=array;

this tells that the pointer has to point to the location 'array'

And, by definition, the location 'array' is the location of the first element

 

but that in fact is not a single location,

Incorrect.

 

To what location should the pointer point then?

See above: by definition, it is the location of the first element

 

with changing it to

>>p=&array[0]

you are actually telling the pointer should be the adress (&)  of location 0

True - but not relevant. An array name is exactly equivalent to the address of the first element.

 

 

http://c-faq.com/aryptr/index.html

 

Last Edited: Fri. Mar 17, 2017 - 07:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Aside from the compiler warning, the statement

 

printf("%c\n",*p);

may print lots of garbage since the string

 

    char array[2];
    array[0]='A';
    array[1]='b';

 

is not zero terminated.

 

It should be:

 

    char array[3];
    array[0]='A';
    array[1]='b';

    array[2]='\0';
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

But he's using %c not %s? It will work and print the first character of the array that p is pointing to.