This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS320F28377D: Compiler-supported method for copying a function pointer to a buffer for debug output

Part Number: TMS320F28377D

Tool/software: TI C/C++ Compiler

For debug purposes, e.g. profiling, I am trying to output an array of function pointers via a stream peripheral, e.g. SPI, UART. This requires converting the function pointers into data so they can be written to the peripheral's transmit register.

I have tried in vain to find a standard C (C89/C90/C99) method for converting from a function pointer to data.

For example, casting from a function pointer to data type is undefined behaviour, regardless of the integer type, be it uint32_t (applicable for this platform), uint64_t, or even uintptr_t:

uint32_t dataFromFunc(void (*func)(void)) {

return (uint32_t)func;

}

Likewise casting from a function pointer to a void (data) pointer is undefined behaviour, so the following is also not allowed due to the implicit cast:

void memcpyFuncToData(void *data, void (*func)(void))

{

memcpy(data, func, sizeof(data));

}

Please can you tell me what method I can use that is supported by the compiler, or do I need to drop down to assembly to avoid the undefined behaviour of what I want to do?

  • IainRist said:
    I have tried in vain to find a standard C (C89/C90/C99) method for converting from a function pointer to data.

    That's because pointers are, by their very nature, not portable values like integers or characters.

    There is no method by which you can satisfy this particular constraint.  Just verify the generated code works as needed, then document that this part of this code works only with the C28x compiler, and will have to be re-implemented if it is ever ported to another system.

    Thanks and regards,

    -George

  • You still run into the no-generic-function-pointer issue, but you could use the %p specifier in sprintf() and put your pointer in a string. I suspect that if you use a cast it will come out OK.

  • Under the its undefined but everyone does it anyway, you could use a union to pick apart your pointer.

  • @George - I have also verified the code generation produces what I want, but with it being undefined behaviour can you (TI) guarantee that this is a defined behaviour of your compiler that you will carry forward (maintain backwards compatability), and if so please can you update the CGT documentation to indicate this?

    Failing that, I believe the 'safest' way for me to convert from function pointer to data is via an assembly function, thereby making it explicit that this is a platform-specific operation.

    @Keith - I agree I could use a union, which was another approach I considered, until I remembered that reading a union member different from the last written union member is unspecified behaviour (C99 standard, J.1 Unspecified Behaviour - "the value of a union member other than the last one stored into").

    I have not verified TI's compiler output, but I did have a collegue bitten once because a (different) compiler reordered the member accesses / read zero.

    I have checked the TI compiler documentation and it does not document if type punning via unions is supported for types of equal size, or for types where the written member is larger than the read member, e.g. union { void (*funcPtr)(void); uint16_t funcAddr[sizeof(void (*)(void)) / sizeof(uint16_t)]; }

  • IainRist said:
    @George - I have also verified the code generation produces what I want, but with it being undefined behaviour can you (TI) guarantee that this is a defined behaviour of your compiler that you will carry forward (maintain backwards compatability)

    Conversion from a function pointer expression to a uintptr_t (a type defined in the standard header file stdint.h) expression, is implemented by copying the bits from the function pointer expression, with no modification, into the uintptr_t expression.  There are no plans to change this implementation.

    IainRist said:
    please can you update the CGT documentation to indicate this?

    I understand why you make this request.  But I'm sorry to have to resist this idea.  This is a detail of very narrow scope.  I think it works better to have this statement appear in a forum thread like this, preceded by the context which leads to it.

    Thanks and regards,

    -George