-3

I am reading a book called "Advanced_C", and tried compiling the sample code "POINTERS.C".

I have built and run it from codeblocks and also tried cc from linux, but I am getting a warning "assignment from incompatible pointer type".

#include <stdio.h>
#include<string.h>

int main(void);

int main()
{

    int nCounter = 33;
    int *pnCounter = (int *)NULL;

    char szSaying[] =
    {
        "Firestone's Law of Forecasting: \n"
        "Chicken Little only has to be right once.\n\n"
    };
    char *pszSaying = (char *)NULL;

    printf(
        "nCounter | pnCounter | *(pnCounter) | pszSaying | "
        "szSaying[0] | szSaying[0-20]\n");

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);

    printf("pnCounter = &nCounter; \n");
        pnCounter = &nCounter;

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);

    printf("pszSaying = szSaying; \n");
        pszSaying = szSaying;

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);

    printf("pszSaying = &szSaying; \n");
    pszSaying = &szSaying;

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);

    printf("pszSaying = &szSaying[0]; \n");
        pszSaying = &szSaying[0];
        printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);

    printf("*(pnCounter) = 1234; \n");
        *(pnCounter) = 1234;

    printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
        nCounter,
        pnCounter,
        *(pnCounter),
        pszSaying,
        *(pszSaying),
        szSaying);
    return (0);
}

I'm new to C programming.

Thanks!

1 Answers1

0

szSaying is declared as an array of chars, and pszSaying is declared as a pointer to char. In the expression:

pszSaying = szSaying,

szSaying, which is an array, is converted to a pointer to char, and the assignment to pszSaying is valid. But, in the espression:

pszSaying = &szSaying

&szSaying is a pointer to an array of chars. This is not the same thing as a pointer to char. This is the reason for the warning about incompatible pointer types.

This is the only warning I get when I compile with gcc file.c -std=c99 -Wall -Wextra -pedantic. Well, there are also a ton of warnings about the %p format specifiers in your calls to printf(). You should cast pointers to (void *) before printing their values.

By casting all of the pointers to (void *) before printing, and modifying these lines:

char (*parrSaying)[] = NULL;

...

printf("parrSaying = &szSaying; \n");
parrSaying = &szSaying;

printf("%8d | %8p | %8d | %8p | %c | %20.20s\n",
       nCounter,
       (void *) pnCounter,
       *(pnCounter),
       (void *) parrSaying,
       (*parrSaying)[0],
       szSaying);

all of the warnings are removed. Here, parrSaying is declared as a pointer to an array of chars, and initialized to NULL. But, having dealt with the warnings, there is another problem: you are attempting to dereference NULL pointers! It is good that you are initializing the pointers to NULL (although there is no reason to cast NULL to (char *) or whatever), because if you didn't these dereferences would be accessing some random locations in memory. But dereferencing a NULL pointer is undefined behavior. You need to move these two pointer assignments so that they occur before the first attempt to dereference and print their values:

pnCounter = &nCounter;
pszSaying = szSaying;

Having made these changes, your code compiles without warnings and runs on my system, giving the following output:

nCounter | pnCounter | *(pnCounter) | pszSaying | szSaying[0] | szSaying[0-20]
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pnCounter = &nCounter; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
parrSaying = &szSaying; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
pszSaying = &szSaying[0]; 
      33 | 0x7ffd3bd36bc4 |       33 | 0x7ffd3bd36be0 | F | Firestone's Law of F
*(pnCounter) = 1234; 
    1234 | 0x7ffd3bd36bc4 |     1234 | 0x7ffd3bd36be0 | F | Firestone's Law of F
Community
  • 1
  • 1
ad absurdum
  • 19,498
  • 5
  • 37
  • 60