This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiling differences between C51 v7.03 and v8.06

Hello!

I have uVision that compiles fine with the C51 v7.03 compiler and the related package, but not complete with the 8.06. I used two different Keil installations. All files are in the same folder.

In the 8.06 I get linker errors like "object does not fit in to pdata page" and "0080H". This looks like the compiler was thinking the PDATA was only 128 bytes, but it is set to 256 bytes in the startup.a51. Any clue what's different in the newer Keil package?

Also there is a warning in 8.06 (which does not show in 7.03) "converting non-pointer to pointer" on this

ptr_xdata = sPtr_obj->Adresse;


while the vars are set like this:

uchar uc_set_obj( uchar pdata *ptr_Set)
{
   uchar i;
   uchar xdata *ptr_xdata;
   struct stOBJADR code *sPtr_obj;

   sPtr_obj=&Obj[*ptr_Set];
   .
   .
   .
   ptr_xdata = sPtr_obj->Adresse;
}


The struct stOBJADR has a member "uint Adresse;"

I can see no wrong use of the pointers. I just want to be sure that the warning does not affect the code to not work correctly.

Parents
  • The Address Of a variable always means the memory address at which that variable itself is located - no ifs, no buts, no exceptions = no confusion;

    The Value Of a variable always means the value stored in the variable itself - again, no ifs, no buts, no exceptions = no confusion;

    How can adding complexity by having the terms mean different things in different contexts be anything but more confusing?!

    A pointer is slightly different. In your terminology the pointer value is the same as a variable's value, because this value is stored in the location (address) of the variable/pointer. But... the pointer also points to a value, not only an address. It points to the value at the address. And how do you call this value? I have no other name than to call it the pointer's value (or pointed value). That's what I always said. For my code it was always important where a pointer points to and what the value of this address was, normal pointer operation that is.

    I still don't get why setting a pointer of type uint to an address given by a value of type uint is conversion or why it is called conversion. For me it is an assignment. Something totally different to a conversion:

    uint *ptr_xdata;
    uint address;
    ptr_xdata = &address;
    

    is logically the same as

    uint some_var;
    struct stObJ{
       uint address;
       uchar object_nr;
    };
    struct stObj *stPtr_Obj;
    stPtr_Obj->address = &some_var;
    ptr_xdata  = stPtr_Obj->address;
    

    like I was writing it all the time and that's why I'm not very delighted (confusion has gone since I managed to figure out what the compilers considers as conversion) about the compiler warning. Because on the upper example it does not warn about conversion. It's not the terminology.

Reply
  • The Address Of a variable always means the memory address at which that variable itself is located - no ifs, no buts, no exceptions = no confusion;

    The Value Of a variable always means the value stored in the variable itself - again, no ifs, no buts, no exceptions = no confusion;

    How can adding complexity by having the terms mean different things in different contexts be anything but more confusing?!

    A pointer is slightly different. In your terminology the pointer value is the same as a variable's value, because this value is stored in the location (address) of the variable/pointer. But... the pointer also points to a value, not only an address. It points to the value at the address. And how do you call this value? I have no other name than to call it the pointer's value (or pointed value). That's what I always said. For my code it was always important where a pointer points to and what the value of this address was, normal pointer operation that is.

    I still don't get why setting a pointer of type uint to an address given by a value of type uint is conversion or why it is called conversion. For me it is an assignment. Something totally different to a conversion:

    uint *ptr_xdata;
    uint address;
    ptr_xdata = &address;
    

    is logically the same as

    uint some_var;
    struct stObJ{
       uint address;
       uchar object_nr;
    };
    struct stObj *stPtr_Obj;
    stPtr_Obj->address = &some_var;
    ptr_xdata  = stPtr_Obj->address;
    

    like I was writing it all the time and that's why I'm not very delighted (confusion has gone since I managed to figure out what the compilers considers as conversion) about the compiler warning. Because on the upper example it does not warn about conversion. It's not the terminology.

Children
  • Only if the replies are constantly saying "you naughty boy, don't you use the wrong terminology" instead of "hmm, the compiler has its own style of warning you. You need to read between the lines".
    Sorry, but you can't back that up. The majority of the text in the replies you have received tries to explain the reason for the naming. But whenever someone says why something is important, you answer with: But I don't care about that. For me xx is the only important thing. You write answers, but you never seem to spend time trying to read the posts before answering to them. Without any bandwidth allocated for input, you can't expect good quality of your output.

    But... the pointer also points to a value, not only an address.
    It does not point to both a value and an adderss. It has an address as it's value. It may point to an address - in case it is a pointer to a pointer. In your case, it is a pointer to a uint, so it does not point to an address - it points to a uint. You have specifically said that you don't care about dual indirection, so your pointers never points to an address...

    confusion has gone since I managed to figure out what the compilers considers as conversion
    Your examples shows that you have not managed to figure out what the compilers consider a conversion. If you did understand your two examples, you should be delighted that the compiler notices the problem with one of them.

    It should be obvious why one case needs a manual (explicit) typecast to make sure you don't get a warning, while the other example does not need neither implicit nor exmplicit type cast.

    &address means "address of uint" and means that there is no need for a typecast - the right-hand side already have the correct data type for assigning to your pointer, since the value of a pointer to uint is an address to uint.

    Assigning &address to a uint means that you throw away the information that the value represents a pointer. The result: Most compilers will warn about the type conversion needed, to convert from uint to "address of uint".

    In this case, the newer version of the compiler has been improved. Some compilers has the special case that they are silent only for assign of the integer value 0 (i.e. a NULL pointer, but complains about any other integer-to-pointer assigns).

  • "A pointer is slightly different."

    It still has an address at which it is stored, and a value which is stored in it - from that point-of-view, it is no different from any other variable.
    Hence there is no reason to give these properties different names - that only causes confusion.

    "It points to the value at the address. And how do you call this value?."

    It is called, very simply, the pointed-to value!

    "I have no other name than to call it the pointer's value (or pointed value)."

    Haven't we already established that doesn't make sense - either in English or in German?

    "The pointer's value" has identical meaning to "the value of the pointer" - the two expressions are equivalent.

    Just as "the car's colour" has identical meaning to "the colour of the car"

    And the value of the pointer (the pointer's value) is not at all the same as the value pointed to by the pointer!

    Try this:

    void main( void )
    {
       int  my_int = 1234;
       int *my_ptr = &my_int;
    
       printf( "The int's value is:            %d\n",   my_int );
       printf( "The value of the int is:       %d\n\n", my_int );
    
       printf( "The address of the int is:     %p\n",   &my_int );
       printf( "The int's address is:          %p\n\n", &my_int );
    
    
       printf( "The pointer's value is:        %p\n",   my_ptr );
       printf( "The value of the pointer is:   %p\n\n", my_ptr );
    
       printf( "The pointer's address is:      %p\n",   &my_ptr );
       printf( "The address of the pointer is: %p\n\n", &my_ptr );
    
       printf( "The pointed-to value is:       %d\n",   *my_ptr );
       printf( "The value pointed to is:       %d\n\n", *my_ptr );
    }
    


    My results with Borland on a PC are:

    The int's value is:            1234
    The value of the int is:       1234
    
    The address of the int is:     0012FF88
    The int's address is:          0012FF88
    
    The pointer's value is:        0012FF88
    The value of the pointer is:   0012FF88
    
    The pointer's address is:      0012FF84
    The address of the pointer is: 0012FF84
    
    The pointed-to value is:       1234
    The value pointed to is:       1234
    

  • "I still don't get why setting a pointer of type uint..."

    STOP right there!

    That is your basic problem: there is no such thing as "a pointer of type uint"

    What you have is a pointer to type uint

    "why it is called conversion."

    Because they are different types!

    "uint" is a type and "pointer to uint" is a different type!

    "For me it is an assignment. Something totally different to a conversion"

    No - it is an assignment that involves a conversion!

    Just as assigning from a float to a uint would involve a conversion (from float to uint).

  • And how do you call this value?

    Value of the dereferenced pointer.

    I still don't get why setting a pointer of type uint to an address given by a value of type uint is conversion or why it is called conversion.

    Because "pointer to uint" and "uint" are two completely different types for the compiler, that need to be treated completely differently in a number of cases.

    Okay, I'll repeat my little quiz for the third time:

    unsigned int some_int = 0;
    unsigned int *some_int_ptr = 0;
    
    some_int++;
    some_int_ptr++;
    

    What is the value of some_int after this snippet ? (that's easy, right) ?

    What's the value of some_int_ptr after this snippet ? (or - is it even possible to answer this question?)

    uint some_var;
    struct stObJ{
       uint address;
       uchar object_nr;
    };
    struct stObj *stPtr_Obj;
    stPtr_Obj->address = &some_var; //  st_ptr_Obj->address is a uint,
                                    // &some_var is a pointer to uint. TYPE CONVERSION.
                                    // (Yes, believe me, it's really really really true)
    ptr_xdata  = stPtr_Obj->address; // ptr_xdata is a pointer to something,
                                     // stPtr_Obj->address is a uint.
                                     // ANOTHER TYPE CONVERSION.
    

    like I was writing it all the time and that's why I'm not very delighted (confusion has gone since I managed to figure out what the compilers considers as conversion) about the compiler warning.

    Believe it or not: The compiler is correct. Your problems with understand this fact and the reasons for it stem from a) misconceptions about the data type "pointer to something" and b) very big misconceptions about what the "member reference from pointer" operator "->" does. "->" does _not_ return an address, it returns a value. Please please please believe it, it's true.

  • uint some_var;
    
    struct stObJ{
       uint  address;
       uchar object_nr;
    };
    
    struct stObj *stPtr_Obj;
    
    stPtr_Obj->address = &some_var;
    ptr_xdata          = stPtr_Obj->address;
    


    Let's take the structure away, as that just complicates it unnecessarily.
    So it boils down to:

    uint  some_var; // A uint
    uint  my_uint;  // Another uint
    uint *my_ptr;   // A pointer to a uint
    
    my_uint = &some_var;
    my_ptr  = my_uint;
    


    So I guess your real question here is:

    Why does

    my_ptr  = my_uint;  // Assign a uint value to a pointer
    

    generate a warning when

    my_uint = &some_var; // Assign a pointer value to uint
    

    doesn't?!

    That's a good question!

    I guess it's becuase the former is more likely to be immediately dangerous than that latter - since a very high proportion of 'C' bugs are due to bad pointers...!

    Remember that 'C' is not a strongly-typed language, so you will only get warnings on things that look really suspicious.

    Clearly, Keil have revised their opinion of what warrants a warning - which is why you get the warning now that you didn't before - but still don't consider the pointer-to-uint worth a warning.