Hot!warning: (2029) a function pointer cannot be used to hold the address of data

Page: 123 > Showing page 1 of 3
Author
the.mark.robertson
New Member
  • Total Posts : 13
  • Reward points : 0
  • Joined: 2018/01/08 12:00:17
  • Location: 0
  • Status: offline
2018/01/09 03:17:44 (permalink)
0

warning: (2029) a function pointer cannot be used to hold the address of data

Can someone advise why warning 2029 is being advised on the code below?  I am not connected to HW so do not know if it is actually compiling/working but it is disconcerting.  Warning is on my load of var onExpiry into .OnExpire.  For info, .OnExpire is defined as a void* and pfSPDEVICE is typedef void(*pfSPDEVICE)(SPDEVICE*);
 
static void _onTickRequest(SPDEVICE* pFrom, U16 ticktime, pfSPDEVICE onExpiry) {
  _tmr_main.Type = SWTIMER_ONCE;
  _tmr_main.Interval = ticktime / SYSTEM_BEATHZ;
  _tmr_main.pUser = (void*)&_tx;
  _tmr_main.OnExpire = (void*)onExpiry;  //throws error 2029
  SWTimer_Start(&_tmr_main);
}
 
I note that this warning is also thrown in your MCC generated EUSART file on these lines:
  EUSART1_SetTxInterruptHandler(EUSART1_Transmit_ISR);
  EUSART1_SetRxInterruptHandler(EUSART1_Receive_ISR);
 
  void EUSART1_SetTxInterruptHandler(void* handler){
    EUSART1_TxDefaultInterruptHandler = handler;
  }
  void EUSART1_SetRxInterruptHandler(void* handler){
    EUSART1_RxDefaultInterruptHandler = handler;
  }
 
 
#1

50 Replies Related Threads

    andersm
    Super Member
    • Total Posts : 2485
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 08:42:27 (permalink)
    0
    If you change the type of .OnExpire to a function pointer and get rid of the void pointer casts, do the warnings go away? On Harvard architecture systems, function and data pointers are usually not freely convertible. (Void pointer casts are evil, don't use them unless absolutely necessary.)
    #2
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 2765
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 09:02:58 (permalink)
    0
    You didn't list, "_tmr_main" structure so how do you expect us to see what the error is?
     
    A cast will not be needed if they are of the same type.
     
    Casting void* - at least cast a size_t of 1 otherwise you can't do any maths.
     
    void *x;
    x++ ;error
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #3
    the.mark.robertson
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2018/01/08 12:00:17
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 09:49:01 (permalink)
    0
    .OnExpire is a function pointer:
    typedef struct {
      SWTIMER_TYPE Type;
      uint8_t Expired;
      uint32_t Interval;
      void* pUser;
      void(*OnExpire)(void*);
      struct {
        uint16_t Remaining;
      } Private;
    } SWTIMER;
     
    I have tried all sorts but the root problem appears to be that whatever is passed as a func.param is treated as data (even if it is a pFunc) and throws an incorrect warning.  Throwing incorrect warnings is bad: it reduces confidence in a product.
     
    XC8 has this warning in its own MCC library funcs (the EUSART lines in original post are MCC, not mine and throw this error).
     
    However, I am open to someone at MC saying this is correct behaviour and explaining why.  Or saying "noted, we'll add it to the list".
    #4
    andersm
    Super Member
    • Total Posts : 2485
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 09:52:36 (permalink)
    0
    In the assignment to OnExpire, you are casting onExpiry to a void pointer. Remove that cast.
    #5
    the.mark.robertson
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2018/01/08 12:00:17
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 09:57:47 (permalink)
    0
    And I get an illegal conversion between pointer types.  Which is why I added casting to match the .OnExpire.  To get rid of that warning.  Which I should be allowed to do.  And which I can do with other compilers.  Just not this one.
    #6
    andersm
    Super Member
    • Total Posts : 2485
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 10:05:07 (permalink)
    0
    What is the signature of onExpiry? 8-bit PICs are not like most other CPUs, there are many things you can't do on them that you can on others.
    #7
    the.mark.robertson
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2018/01/08 12:00:17
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 10:11:59 (permalink)
    0
    If anyone else has something to add I'd welcome it.
     
    #8
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 2765
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 10:27:59 (permalink)
    0
    Don't blame the tools.
    List that structure: _tmr_main
     
    People come here because they are stuck yet never reveal all of the code.
     
    It looks messy.
     
    SWTIMER  looks like a macro to someone reading your code
    SWTimer_t
     
    If you want private vars there are otherways of hiding that.
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #9
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 2765
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 10:32:21 (permalink)
    0
    Just to add:
     
    Don't fit your code around compiler errors by casting if the code was wrong in the first  place.
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #10
    jtemples
    Super Member
    • Total Posts : 11018
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 11:49:47 (permalink)
    +1 (1)
    Which is why I added casting to match the .OnExpire.  To get rid of that warning.  Which I should be allowed to do.

     
    Function and object pointers are not interchangeable in standard C.  The fact that some other compiler allows this as an extension is irrelevant.
    #11
    Peter Sikora
    Super Member
    • Total Posts : 132
    • Reward points : 0
    • Joined: 2003/11/07 12:46:46
    • Location: Brisbane Australia
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 13:34:20 (permalink)
    0
    What are you trying to do by declaring your function pointer in the struct? I am thinking you should just have
    void* OnExpire in the struct as a member. Correct me if I am wrong here.
    #12
    DavidBLit
    Super Member
    • Total Posts : 1574
    • Reward points : 0
    • Joined: 2012/02/18 13:08:48
    • Location: The Land of Confusion
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 14:50:31 (permalink)
    0
    conelec
    What are you trying to do by declaring your function pointer in the struct? I am thinking you should just have
    void* OnExpire in the struct as a member. Correct me if I am wrong here.

    OnExpire is intended to be a the address of a function called upon timer expiry (with pUser as the argument).

    Yeah, "//Code and stuff".
    #13
    Peter Sikora
    Super Member
    • Total Posts : 132
    • Reward points : 0
    • Joined: 2003/11/07 12:46:46
    • Location: Brisbane Australia
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 15:16:56 (permalink)
    -1 (1)
    Well all you need to do is declare it as a void* member in your struct. I have a similar set up to run a function that is delivered from touch panel input. I have a GetFunction procedure that retrieves the address of a function pointer from a linked list.
    typedef struct T_SYS_MSG{
    OBJ_TYPE Type; // Device responsible for the message used to TYPE the void pointer
    DEVICE Device; // from list of possible I/O Devices
    int Event; // Generic device event codes.
    int ObjID; // ObjectID of Object
    int param1; // Parameter 1 interpretation is 'device' dependent.
    int param2; // Parameter 2 interpretation is 'device' dependent.
    void* pObjFunc; // function pointer to the object message function
    void* pObject; // Object Pointer
    }SYS_MSG; // System Message Struct Defined

     
    The message store is created  as SYS_MSG Msg;
    Pointer assigned to the message store SYS_MSG* pMsg = &Msg;
     
    so if I have "SomeFunction()" simply store the pointer as, pMsg->pObject = &SomeFunction;
     
    I then have general function pointer function declared as, void (*ObjFunc)(SYS_MSG* pMsg);
    when my main loop gets a message to process
    // retrieve the function address from the message
    ObjFunc = pMsg->pObjFunc;
    if ((*ObjFunc) == NULL){} else { (*ObjFunc)(pMsg);} // Do not run a null function pointer.
    This works for me. While I am no "expert" in C a function pointer is just an address after all.
     
     
     
    #14
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 15:18:04 (permalink)
    +2 (2)
    the.mark.robertson
    And I get an illegal conversion between pointer types.  Which is why I added casting to match the .OnExpire.  To get rid of that warning.  Which I should be allowed to do.  And which I can do with other compilers.  Just not this one.


     
    Your function pointer cast should be:

     
     _tmr_main.OnExpire = (void (*)(void *))onExpiry;
     

    The two function pointers in your case are different because the input arguments are of different types, i.e., void * vs. SPDEVICE *.
    post edited by aschen0866 - 2018/01/09 15:23:04
    #15
    jtemples
    Super Member
    • Total Posts : 11018
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 15:36:45 (permalink)
    +1 (1)
    Well all you need to do is declare it as a void* member in your struct

     
    As I mentioned above, converting data pointers to function pointers or vice versa is not standard C, and XC8 does not allow it.  Your code is relying on a compiler extension.
     
    #16
    jtemples
    Super Member
    • Total Posts : 11018
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 15:46:41 (permalink)
    0
     _tmr_main.OnExpire = (void (*)(void *))onExpiry;

     
    This is legal, and will *probably* work, but I believe calling the function through that pointer is undefined behavior because it's not a compatible type.
    #17
    Peter Sikora
    Super Member
    • Total Posts : 132
    • Reward points : 0
    • Joined: 2003/11/07 12:46:46
    • Location: Brisbane Australia
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 15:54:13 (permalink)
    -1 (1)
    @jtemples. I don't see that he wants to convert pointers. I just think he has declared the member of the struct incorrectly and that's why he is getting that warning message. Can you elaborate?
    #18
    jtemples
    Super Member
    • Total Posts : 11018
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 16:27:06 (permalink)
    +1 (1)
    conelec
    @jtemples. I don't see that he wants to convert pointers

     
    His code has the same issue yours does:  attempting to use a void* to store a function pointer.  That's not a legal conversion.
    #19
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: warning: (2029) a function pointer cannot be used to hold the address of data 2018/01/09 16:56:31 (permalink)
    +1 (1)
    John, I think the OP's problem is really due to two incompatible function pointers. The (void *) casting only makes the matter worse as it is now seen, by the compiler, as trying to convert between a data pointer and a function pointer.
     
    It is obvious the OP is trying to implement a timer callback. In this case, the best solution seems to either changing
    typedef void(*pfSPDEVICE)(SPDEVICE*);
    to
    typedef void(*pfSPDEVICE)(void*);
     
    or perform the pointer casting, which is really an undefined behavior as far as the Standard is concerned.
     
    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2018 APG vNext Commercial Version 4.5