• AVR Freaks

Hot!Endless frustrating fight against XC8

Author
olifri
New Member
  • Total Posts : 2
  • Reward points : 0
  • Joined: 2019/11/21 10:50:22
  • Location: South West Germany
  • Status: offline
2021/01/18 10:04:08 (permalink)
2.5 (2)

Endless frustrating fight against XC8

I feel it increasing a pain in the ass to work with XC8 2.31 and want to ask for help whether it is so buggy or if I misunderstand some basic concepts of a C-Compiler or the C language in general:-(
 
My setup is:
- Ubuntu 20.04 LTS
- MPLABX 5.45
- XC8 2.31
- PIC18F2320
 
Some two or three years ago I wrote code for the PIC18F2320 with the actual XC8 at the time, must be XC8 1.41 or similar. That project went rather smooth and the code was running to my satisfaction.
Now I wanted to compile that code with the new XC8 2.31 and finally gave it up, due to endless lists of errors and warnings...I could not get it to compile.
 
Now I have started to build the code from scratch with the new setup and this XC8 just ticks me off with its fanatic code optimization.
It seems to me, that coding has turned into an endless fight to prevent the compiler from discarding code what "he" thinks is useless.
 
 
Enough said. I want to
 
- switch off the code optimization and make the compiler compile my code, regardless of it useful or useless. Just fucking compile it and do not save RAM or program memory without being approved to do so...it is my code and not yours!
- I want to code some small examples that show a certain problem I want you to help me solve it.
 
As a beginning: The following small program does not work because XC8 considers state2 function as not used and therefor optimizes away...

/*
 * File: main.c
 * Author: oliver
 *
 * Created on 30. Dezember 2020, 09:15
 */


#include <xc.h>
void* state1(void);
void* state2(void);


void main(void) {
    
    void* (*state)(void);
    
    state = state1;
    while(1){
        
        state = state();
    }
}

void* state1(void){
    
    return state2;
}

void* state2(void){
   
    return state1;
}

I know, that code does nothing, but that's not the point! I want to develop this example until it implements the problem. But even at the earliest stage I have to bother to defend my code from being dumped by the compiler:-(
 
 
Thank you for your patience and assistance
 
Oli
 
 
 
 
#1

13 Replies Related Threads

    mlp
    boots too small
    • Total Posts : 1005
    • Reward points : 0
    • Joined: 2012/09/10 15:12:07
    • Location: previously Microchip XC8 team
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/18 15:45:18 (permalink)
    +2 (4)
    olifri
    I misunderstand some basic concepts of ... the C language

    void* state1(void);
    void* state2(void);

    void* state1(void){
        return state2;
    }

    void* state2(void){
        return state1;
    }


    The compiler surely warned you about the type mismatches in your two example functions.
    You first tell the compiler that each function will return a value of type pointer-to-void, but then you attempt to return a value of type pointer-to-(function-returning-pointer-to-void).
     
    What you want to do here can't strictly be done in C.
    See http://c-faq.com/decl/recurfuncp.html
     
    If you can avoid pointers-to-functions in PIC code you will be much happier. The 8-bit PICs all have very function-pointer-unfriendly architectures.
    post edited by mlp - 2021/01/18 15:52:11

    Mark (this opinion available for hire)
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 19146
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/18 17:15:32 (permalink)
    0
    XC8 Version 1.41 (Still Available) is a C90 Compiler
    XC8 V2.31 will Default to C99.  This is why you can not build your Original Code.
    You can Get an Use the Original Compiler.
    Or you can Use V2.31  by selecting C90 Mode.
     
    And No The Compiler being Buggy is not the Issue here.
    The Compiler is tossing code because it is not being used.  If it is wrong, it is because you have issues in your code.  Or you are being very clever with pointers.  It is an Optimizing Compiler.  That is what it does.  Why fight with it?
    #3
    Mysil
    Super Member
    • Total Posts : 4114
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/18 17:28:24 (permalink)
    0
    Hi,
     
    MCC use function pointers quite regularly, and it work there.
    However, it do not pass function pointers around as function retirn values.
     
    In I2C  driver code for Master mode, there is a state machine using a array of function pointers,
    passing the index into the array of function pointers, as function return value.
     
    You may look at how it is done there.
     
        Mysil
    #4
    Murton Pike Systems
    Super Member
    • Total Posts : 223
    • Reward points : 0
    • Joined: 2020/09/10 02:13:01
    • Location: 0
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/18 19:20:31 (permalink)
    +1 (1)
    A fussy compiler isnt always bad as it can sometimes pick up warnings/errors that an unfussy one might not.
     
    The code optimisation can be a pig. I havent noticed it too much with xc8 but in xc32 it starts removing artificial delay loops !
    #5
    ric
    Super Member
    • Total Posts : 29870
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Endless frustrating fight against XC8 2021/01/18 19:24:24 (permalink)
    +4 (4)
    nigelwright7558
     I havent noticed it too much with xc8 but in xc32 it starts removing artificial delay loops !

    XC8 will remove "do nothing" loops if the count variable is not "volatile".
    That is why they supply delay macros that will never be optimised away.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    Murton Pike Systems
    Super Member
    • Total Posts : 223
    • Reward points : 0
    • Joined: 2020/09/10 02:13:01
    • Location: 0
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/18 19:34:04 (permalink)
    +1 (1)
    ric
    XC8 will remove "do nothing" loops if the count variable is not "volatile".
    That is why they supply delay macros that will never be optimised away.

    I use volatile quite a bit in PIC32 especially for DMA as the DMA moves code without updating the cache.
    I also used the  __delay_ms(); in XC8, probably why I didnt spot it removed delay loops.
    There is no delay_ in PIC32 (as far as I know) you have to use timers.
     
    #7
    oliverb
    Super Member
    • Total Posts : 403
    • Reward points : 0
    • Joined: 2009/02/16 13:12:38
    • Location: 0
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/19 04:49:36 (permalink)
    0
    I haven't checked but can you prevent a function being optimised away by dummy calling it after the while loop, or does the compiler recognise that the dummy calls aren't reachable?
     
    #8
    1and0
    Access is Denied
    • Total Posts : 12086
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/19 05:37:34 (permalink)
    +1 (1)
    oliverb
    I haven't checked but can you prevent a function being optimised away by dummy calling it after the while loop, or does the compiler recognise that the dummy calls aren't reachable?

    That will use and waste code space. Just declare an assembly symbol for the function name:
    asm("global _func");

    void func(void)
    {
        // insert code
    }

     
    #9
    olifri
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2019/11/21 10:50:22
    • Location: South West Germany
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/24 02:19:39 (permalink)
    +1 (1)
    mark.pappin
     
    The compiler surely warned you about the type mismatches in your two example functions.
    You first tell the compiler that each function will return a value of type pointer-to-void, but then you attempt to return a value of type pointer-to-(function-returning-pointer-to-void).
     
    What you want to do here can't strictly be done in C.
    See http://c-faq.com/decl/recurfuncp.html
     
    If you can avoid pointers-to-functions in PIC code you will be much happier. The 8-bit PICs all have very function-pointer-unfriendly architectures.




    Sorry for responding so late, I had to sort out a few things first.
    First of all, thank you for everybody's response.
    Although, I could not see the "truth" in the quoted answer from mark.pappin in the first place, it turned out to be the solution to all my troubles and pain. THANK YOU, Mark;-)
    I rewrote my code and got rid of the passing around function pointers and my code is running flawlessly ever since.
     
    THANK YOU!
    So, that was a pretty hard lesson to learn...but
     
    a) As far as I can remember the compiler never issued any warnings regarding type mismatch!
     
    b) Matter of fact, the function pointer stuff itself was working...but obviously had any number of nasty side effects and this is what I call bad behaviour!
     
    c) I do not agree with your argument, that I should avoid function pointers due to lack of support by the architecture. I can sure do function pointer in assembly language, so the architecture is ready for it. And then I expect the compiler to implement that stuff in a proper way or just to refuse to compile if "he" is unsure.
     
    d) My code from some two years ago had almost exactly the same architecture, also utilizing the function pointer design pattern...and I never had any trouble with that code and XC8 1.44. So, I definetely blame the compiler!
     
    NKurzman
    XC8 Version 1.41 (Still Available) is a C90 Compiler
    XC8 V2.31 will Default to C99.  This is why you can not build your Original Code.
    You can Get an Use the Original Compiler.
    Or you can Use V2.31  by selecting C90 Mode.
     
    And No The Compiler being Buggy is not the Issue here.
    The Compiler is tossing code because it is not being used.  If it is wrong, it is because you have issues in your code.  Or you are being very clever with pointers.  It is an Optimizing Compiler.  That is what it does.  Why fight with it?




    Yes, you are right, from the compiler's point of view, my example is totally useless. But isn't it up to the designer to decide if he wants to write "useless" code?
    In my very example I couldn't even provide you a example of my bug, which I wanted to show to you...because the compiler didn't let me build up an example that comes to the point...because it spoils all my attempts from the very beginning, influencing and bend the code to what "he" believes is ...kind of "useful":-( F##k off!
     
    I have searched the web for the one golden option that turns off optimization globally and prevent the compiler from making any assumptions of "use".
    Although, my project settings clearly shows "XC8 Compiler -> Optimizations->Optimization level: 0" DO NOT OPTIMIZE, it optimizes...That's what I call buggy behaviour, isn't it?
     
    Declaring variables as "volatile", calling functions after the while(1) loop, declaring assembly symbols...just to desperately prevent the compiler from screw up your code...THAT is what produces useless, hard to read and ugly code!
     
    Greetings
    Oli
     
     
    #10
    ric
    Super Member
    • Total Posts : 29870
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Endless frustrating fight against XC8 2021/01/24 02:59:16 (permalink)
    +2 (2)
    The XC8 compiler uses a "compiled stack" to work around the lack of a data stack in most 8 bit PICs.
    For this to work efficiently, it has to build a complete tree of how your code works, ignoring any function that is never called. Function pointer use makes this much trickier.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    1and0
    Access is Denied
    • Total Posts : 12086
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/24 04:51:20 (permalink)
    0
    olifri
    Although, my project settings clearly shows "XC8 Compiler -> Optimizations->Optimization level: 0" DO NOT OPTIMIZE, it optimizes...That's what I call buggy behaviour, isn't it?

    I fell for that too. :(  It still optimizes.  It can even change your assembly code!
     

    Declaring variables as "volatile", calling functions after the while(1) loop, declaring assembly symbols...just to desperately prevent the compiler from screw up your code...THAT is what produces useless, hard to read and ugly code!

    Yeah!
     
    #12
    NKurzman
    A Guy on the Net
    • Total Posts : 19146
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/24 09:07:30 (permalink)
    0
    If you don’t want to compiler to use the compiled stack you can turn that off to.
    But be prepared for a performance hit.
    And an increase in memory use.
    #13
    mlp
    boots too small
    • Total Posts : 1005
    • Reward points : 0
    • Joined: 2012/09/10 15:12:07
    • Location: previously Microchip XC8 team
    • Status: offline
    Re: Endless frustrating fight against XC8 2021/01/24 18:42:23 (permalink)
    0 (2)
    olifri
    Although, I could not see the "truth" in the quoted answer from mark.pappin in the first place, it turned out to be the solution to all my troubles and pain. THANK YOU, Mark;-)

    You're welcome.
     
    a) As far as I can remember the compiler never issued any warnings regarding type mismatch!

    Maybe it's not as smart as I thought it was.
     
    c) I do not agree with your argument, that I should avoid function pointers due to lack of support by the architecture.

    I didn't say "lack of support"; I said "unfriendly". Argue further when you've written a C compiler for this architecture.
     
     
    isn't it up to the designer to decide if he wants to write "useless" code?

    Sure, until he hands it to an optimizing compiler for a resource-constrained architecture.
     
     
    In everything, just because you Can, doesn't mean you Should.

    Mark (this opinion available for hire)
    #14
    Jump to:
    © 2021 APG vNext Commercial Version 4.5