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

for(N = List->Head;N;N = N->Succ)

struct NODE{
    struct NODE Succ;
    struct NODE Prev;
};

struct LIST{
    struct NODE *Head;
    struct NODE *Tail;
    int count;
};

struct LIST *List;
struct NODE *N;

......
for(N = List->Head;N;N = N->Succ)
{
    ......
}
Compiler C51 changed value of List->Head because of the side effect of N = N->Succ.What can I do?

Parents
  • I tried two different settings (using optimization level 0 and 8)under Large Memory Model,When using level 8,N and List were located in the same memory address,but when level 0,they weren't.
    Level 8:

    SYMBOL TABLE OF MODULE:  test (MAIN)
    
          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          0200000EH   PUBLIC    XDATA    ---       SecondNode
          02000006H   PUBLIC    XDATA    ---       MyList
          02000000H   PUBLIC    XDATA    ---       FirstNode
          01000003H   PUBLIC    CODE     ---       main
    
          01000003H   BLOCK     CODE     ---       LVL=0
          00000001H   SYMBOL    DATA     ---       List
          00000001H   SYMBOL    DATA     ---       N
          ---         BLOCKEND  ---      ---       LVL=0
    
    Level 0:
    SYMBOL TABLE OF MODULE:  test (MAIN)
    
          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          0200000EH   PUBLIC    XDATA    ---       SecondNode
          02000006H   PUBLIC    XDATA    ---       MyList
          02000000H   PUBLIC    XDATA    ---       FirstNode
          01000003H   PUBLIC    CODE     ---       main
    
          01000003H   BLOCK     CODE     ---       LVL=0
          02000014H   SYMBOL    XDATA    ---       List
          02000017H   SYMBOL    XDATA    ---       N
          ---         BLOCKEND  ---      ---       LVL=0
    

Reply
  • I tried two different settings (using optimization level 0 and 8)under Large Memory Model,When using level 8,N and List were located in the same memory address,but when level 0,they weren't.
    Level 8:

    SYMBOL TABLE OF MODULE:  test (MAIN)
    
          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          0200000EH   PUBLIC    XDATA    ---       SecondNode
          02000006H   PUBLIC    XDATA    ---       MyList
          02000000H   PUBLIC    XDATA    ---       FirstNode
          01000003H   PUBLIC    CODE     ---       main
    
          01000003H   BLOCK     CODE     ---       LVL=0
          00000001H   SYMBOL    DATA     ---       List
          00000001H   SYMBOL    DATA     ---       N
          ---         BLOCKEND  ---      ---       LVL=0
    
    Level 0:
    SYMBOL TABLE OF MODULE:  test (MAIN)
    
          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          0200000EH   PUBLIC    XDATA    ---       SecondNode
          02000006H   PUBLIC    XDATA    ---       MyList
          02000000H   PUBLIC    XDATA    ---       FirstNode
          01000003H   PUBLIC    CODE     ---       main
    
          01000003H   BLOCK     CODE     ---       LVL=0
          02000014H   SYMBOL    XDATA    ---       List
          02000017H   SYMBOL    XDATA    ---       N
          ---         BLOCKEND  ---      ---       LVL=0
    

Children
  • Ok, I stripped down the code: optimization level 8, large (code/data), generic 8051 device

    struct NODE{
        struct NODE *Succ;
        struct NODE *Prev;
    };
    
    struct LIST{
        struct NODE *Head;
        struct NODE *Tail;
        int count;
    };
    
    main()
    {
        struct LIST *List;
        struct NODE *N;
    
        // loop over all nodes
        for(N = List->Head;N;N = N->Succ)
        {
        }
    }
    
    -> MAP file (looks a bit different to yours): List and N are on different memory locations.
          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          0100004AH   PUBLIC    CODE     ---       main
    
          0100004AH   BLOCK     CODE     ---       LVL=0
          0100004AH   BLOCK     CODE     NEAR LAB  LVL=1
          02000000H   SYMBOL    XDATA    ---       List
          00000001H   SYMBOL    DATA     ---       N
          ---         BLOCKEND  ---      ---       LVL=1
          ---         BLOCKEND  ---      ---       LVL=0
    
    Why does your main() start at C:0x0003?

  • I'm baffled as to why "List" seems to be being placed in xdata in your map file.

    If I compile this code in the small memory model, all variables are placed in DATA. List and N are placed at the same address, however I think this is because N is never used in the code hence it doesn't matter where it is placed:

    struct NODE{
    struct NODE *Succ;
    struct NODE *Prev;
    };

    struct LIST{
    struct NODE *Head;
    struct NODE *Tail;
    int count;
    };

    struct LIST MyList;
    struct NODE FirstNode;
    struct NODE SecondNode;

    main()
    {
    struct LIST *List;
    struct NODE *N;

    // init nodes and list
    FirstNode.Succ = &SecondNode;
    FirstNode.Prev = 0;
    SecondNode.Succ = 0;
    SecondNode.Prev = &FirstNode;
    MyList.Head = &FirstNode;
    MyList.Tail = &SecondNode;
    MyList.count = 2;

    List = &MyList;

    // loop over all nodes
    for(N = List->Head;N;N = N->Succ)
    {
    }

    }

    VALUE REP CLASS TYPE SYMBOL NAME
    ====================================================
    --- MODULE --- --- JUNK
    00000016H PUBLIC DATA --- SecondNode
    00000010H PUBLIC DATA --- FirstNode
    00000008H PUBLIC DATA --- MyList
    01000003H PUBLIC CODE --- main

    01000003H BLOCK CODE --- LVL=0
    00000001H SYMBOL DATA --- List
    00000001H SYMBOL DATA --- N
    01000003H LINE CODE --- #44
    01000003H LINE CODE --- #45
    01000003H LINE CODE --- #50
    0100000CH LINE CODE --- #51
    01000015H LINE CODE --- #52
    0100001EH LINE CODE --- #53
    01000027H LINE CODE --- #54
    01000030H LINE CODE --- #55
    01000039H LINE CODE --- #56
    0100003FH LINE CODE --- #58
    01000045H LINE CODE --- #61
    0100004BH LINE CODE --- #62
    0100004BH LINE CODE --- #63
    0100004FH LINE CODE --- #65
    --- BLOCKEND --- --- LVL=0


    However, if I initialise N:

    struct NODE{
    struct NODE *Succ;
    struct NODE *Prev;
    };

    struct LIST{
    struct NODE *Head;
    struct NODE *Tail;
    int count;
    };

    struct LIST MyList;
    struct NODE FirstNode;
    struct NODE SecondNode;

    main()
    {
    struct LIST *List;
    struct NODE *N;

    // init nodes and list
    FirstNode.Succ = &SecondNode;
    FirstNode.Prev = 0;
    SecondNode.Succ = 0;
    SecondNode.Prev = &FirstNode;
    MyList.Head = &FirstNode;
    MyList.Tail = &SecondNode;
    MyList.count = 2;

    List = &MyList;
    N=&FirstNode;
    // loop over all nodes
    for(N = List->Head;N;N = N->Succ)
    {
    }

    }

    VALUE REP CLASS TYPE SYMBOL NAME
    ====================================================
    --- MODULE --- --- JUNK
    00000016H PUBLIC DATA --- SecondNode
    00000010H PUBLIC DATA --- FirstNode
    00000008H PUBLIC DATA --- MyList
    01000003H PUBLIC CODE --- main

    01000003H BLOCK CODE --- LVL=0
    0000001CH SYMBOL DATA --- List
    00000001H SYMBOL DATA --- N
    01000003H LINE CODE --- #44
    01000003H LINE CODE --- #45
    01000003H LINE CODE --- #50
    0100000CH LINE CODE --- #51
    01000015H LINE CODE --- #52
    0100001EH LINE CODE --- #53
    01000027H LINE CODE --- #54
    01000030H LINE CODE --- #55
    01000039H LINE CODE --- #56
    0100003FH LINE CODE --- #58
    01000048H LINE CODE --- #59
    01000048H LINE CODE --- #61
    01000054H LINE CODE --- #62
    01000054H LINE CODE --- #63
    01000058H LINE CODE --- #65
    --- BLOCKEND --- --- LVL=0

    Stefan

  • List is placed in XDATA because I use the large memory model (see message)...

    "N is never used in the code hence it doesn't matter where it is placed:
    "

    N is used in code: "N = List->Head" and "N = N->Succ" in the for-loop.

    In small model I get the following map-file:

          VALUE       REP       CLASS    TYPE      SYMBOL NAME
          ====================================================
          ---         MODULE    ---      ---       MAIN
          01000003H   PUBLIC    CODE     ---       main
    
          01000003H   BLOCK     CODE     ---       LVL=0
          01000003H   BLOCK     CODE     NEAR LAB  LVL=1
          00000008H   SYMBOL    DATA     ---       List
          00000001H   SYMBOL    DATA     ---       N
          ---         BLOCKEND  ---      ---       LVL=1
          ---         BLOCKEND  ---      ---       LVL=0
    
    N and List are still on different locations! The compiler generates code for the for-loop (optimization level 8!)

    Maybe a compiler/linker version problem?

    My versions are:
    C51: V7.06
    LX51: V3.58d
    (AX51: V2.09)

  • "List is placed in XDATA because I use the large memory model"

    Ok, but shouldn't N therefore be placed in xdata as well? Quoting from your map file above:

    02000000H SYMBOL XDATA --- List
    00000001H SYMBOL DATA --- N

    "N is used in code: "N = List->Head" and "N = N->Succ" in the for-loop"

    Yes, I must have been sleeping. Again.

    I think Hans is right, the optimisation is legitimately causing this. The order of events is (pseudocode):

    List=An address;
    N=List->Head;
    LABEL:
    N=N->Succ;
    if(N) goto LABEL

    So, List and N can occupy the same location without anything going wrong.

    Stefan