Thread: warning assignment from incompatable pointer type

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    warning assignment from incompatable pointer type

    i know what i have done im just curious why i got the warning
    Code:
    void adder_month(Lists *calender, Months_Node *node)
    {
        if ( calender->current_day == NULL )
        {
            // empty
            calender->current_day = node;
            node->next = node;
        }
        else
        {
            // more than one node
            node->next = calender->current_month->next; // A
            calender->current_month->next = node;       // B
            calender->current_month = node;             // C
        }
    }
    when i copied and pasted the code i forgot to change current_day to current_month easily fixed. but the question arrises both current day and current month are pointers to two structs. both structs hold an int and a char pointer and a next pointer of thier respective names if malloc doesnt have to be cast in the sense that malloc(some number) would do for a char * how did the compiler pick this up.... but doesn't second guess you on other issues like over addressing an array. or is that a complicated question.

  2. #2
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    funny enough it only picked up one the one side of the if statement not the one controlling the if statement. Note to self don't cut and paste with out reading it all first

  3. #3
    Registered User
    Join Date
    May 2019
    Posts
    214
    It's been a while since I've written in C, so when I see this I apply my C++ instincts first and have to remind myself this isn't C++, it's C. I come from a time before C++, and I wrote in C for years, but I'm realizing how far back I have to reach to remember this (around 30 years).

    First, type still means something. The fact that two structures have otherwise identical contents means nothing to the compiler, if the names of the types involved aren't the same then the types may not be the same. The two structs you think of being the same design are still two separate structs to the compiler.

    That said, realize that the type of the return from malloc is not a number. The type is a void *. I know it looks like a number (indeed, it is an unsigned integer in reality), but the type is not a number. It is a void *. That means something different to C than it does to C++, and I have to think really hard about that to remember.

    In C there's no complain assigning a pointer of any type to a void pointer. The compiler takes that to mean you're in charge, determining that the void * returned from malloc represents, to you, a pointer to whatever you're assigning it to. Thus,

    Code:
    void *x = malloc( sizeof( Months_Node ) );
    
    Months_Node *mn = x;
    This does not generate a complaint from the compiler, and as far as the compiler is concerned, since x is a void *, assignment of a Months_Node pointer to x is no different than assigning it to what was returned from the malloc. They are both void pointers and the compiler is fine doing that (in C++, it isn't - it's an error, not just a warning).

    Now, this is a problem:

    Code:
    Day_Node *dn = malloc( sizeof( Day_Node ) );
    Months_Node *mn = dn;
    This generates a warning from C (an error in C++), and it is because Day_Node and Months_Node are different types. Despite the layout and content being similar or identical, the types are generated separately as separate structs and are not likely compatible in the compiler's view. It may allow it, but chances are you're not getting what you expect.

    Code:
    Months_Node *mn1 = 0;
    Months_Node *mn2 = (void *)0;
    Months_Node *mn3 = NULL;
    For C, NULL is defined. How it is defined may depend on the compiler. Some may define it as the assigment in mn2, others may define it as the assignment in mn1, and you'll find all 3 of these compile without issue in C. That's because the compiler does "understand" that the pointer is set to a zero value (a null pointer) that is reasonable to do. It can be compared in that way, too, without confusion. This isn't true in C++ (types are a little stricter there), but in the underlying truth of what it means to "be" a pointer, assignment to zero or comparison to zero is a rather obviously sane thing to do and does not really invoke any issues with type here.

    Note, however, this is not so easily passed by the compiler:

    Code:
    Months_Node *mn1 = 2;
    This would generate a warning at least. Here, the compiler is noticing that a pointer is assigned to an integer, and that DOESN'T make much sense. Assignment to zero did, and so the context may well ignore that 0 is an integer type - it just happens to be a special integer where 0 has relevance to the content of a pointer, but 2 (or any integer) doesn't - without there being some curious context to make it work.

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    wow thank you for the explanation

    just to clarify because im thick because i have two different struct names/ tags they are two different types despite the fact they are both structs. Just like an int is a different type to a char for example. i also know understand why someone said (char *)malloc(x +1) was fine but the cast to char * was redundant i was thinking that what ever you put in the brackets of malloc was the type of pointer you got out unless you cast it what was obviously incorrect thinking and i can see indeed that in c i don't need the cast to char *.

    20 some years ago i did an electronic engineering course at collage and we had to do a class on microprocessors it ended up with us writing "programs" in assembly for the 6800 chip. we would have to give it register addresses to store variables. In c if one knew that a specific memory address was safe to use could one assign a pointer to that address by giving it a hex value ie *mypointer = 0x2f if we knew the location 18 was ok. Obviously this is unnecerserry in modern machines with gigs of ram but im thinking in the cases of small pi's or arduous with only a 1mb.

    coop

  5. #5
    Registered User
    Join Date
    May 2019
    Posts
    214
    @cooper1200, you have that right about structs. It is not that "struct" is a type, but what you create with the struct keyword that is a type. In that sense, structs are a custom/user created types (the programmer is the user in this case).

    Also, about malloc - what you used to think became what in C++ is using the "new" keyword, but malloc only ever returned a void *.

    could one assign a pointer to that address by giving it a hex value ie *mypointer = 0x2f if we knew the location 18 was ok
    It's actually more interesting than just that. One reason you did that in the 6800 assembler was probably the fact there was no operating system, or it was a very primitive one.

    In modern work if you were writing an operating system, you'd be doing just that when you write the memory management features which give memory to processes. Remember, C was first created to write the UNIX operating system. C is, in that perspective, an assembler that is chip independent and with some high level features.

    Some 40 years ago I built one of my first computers using the 6800. It was a kit that came in a notebook, circuit board, parts and instructions. I walked through high school using that notebook for class. Most of the computers I had in the 70's were either 6502 or Z80. Indeed, the 6502 started out as a plug in replacement for the 6800, but did so without permission from Motorola. The company re-wired the chip so it would not fit into the same socket just to avoid legal implications, but the two were closely related for many years.

  6. #6
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    no no operating system just 8 segment lcds to display the output and a keypad with 0-9 and A-F and an enter i think. Unfortunately looking back it was proberbly a class i would of got a lot out of. but the lecturer was old school and didn't take any prisoners if you missed a class even for a valid reason (one of my class mates child was run over) he deemed that as your problem and you had to catch up from your class mates. the trouble was they probably didn't understand it either. needless to say everyone dropped at least one grade on his course.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. assignment from incompatable pointer
    By cooper1200 in forum C Programming
    Replies: 4
    Last Post: 05-31-2019, 03:48 PM
  2. Replies: 1
    Last Post: 04-09-2017, 02:11 PM
  3. Replies: 21
    Last Post: 11-25-2014, 12:30 PM
  4. warning: assignment from incompatible pointer type.
    By ingeniousreader in forum C Programming
    Replies: 4
    Last Post: 03-06-2012, 09:00 AM
  5. warning: assignment from a incompatible pointer type
    By enderandrew in forum C Programming
    Replies: 8
    Last Post: 09-22-2007, 04:07 AM

Tags for this Thread