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

Compier checks section under #ifdef UNDEFINED -> error

It seems a bug crept in CC ARM, may be not only ARM. Consider next code:

#ifdef IDENTIFIER
    IDENTIFIER();
#endif

and build output:

..\..\src\module\module.cpp(344): error:  #20: identifier "IDENTIFIER" is undefined


GCC does not have such problem. Check <a href=coliru.stacked-crooked.com/.../7e6350bd2bfbc14a >here</a>

  • It seems a bug crept in CC ARM

    Nonsense.

    Do you have any idea about the difference between the compiler and the preprocessor?

  • If you had written:

    #define IDENTIFIER charlie
    
    #ifdef IDENTIFIER
        IDENTIFIER()
    #endif
    

    Then IDENTIFIER would have been defined and you would have ended up with:

        charlie()
    


    And the compiler - and later linker - would have to figure out if any function named "charlie" exists.

    But I don't think your code contains any:

    #define IDENTIFIER charlie
    

    So what would happen if IDENTIFIER would expand to something else? Remember that you might even go all the way and have:

    #define IDENTIFIER
    


    where you haven't given IDENTIFIER any specific value to expand to. This is also covered by the standard.

  • Do you have any idea about the difference between the compiler and the preprocessor?
    Ok, it's supposed toolchain. You play with words. For end customer|programmer|me this doesn't metter.

  • In addition

    //#define LED  PA7
    #ifdef LED
        led_on(LED);  //if 1st string commented, we will get an error "undefined identifier"
    #endif
    

    I have found workaround

    #define LED  0 //PA7
    #if LED
        led_on(LED);
    #endif
    

    But I would like to have ability to undefine LED at all.

  • > #define IDENTIFIER
    I know write so sometimes. Take a look too may another message, where IDENTIFIER is function argument.

    func(IDENTIFIER)
    

  • //#define LED  PA7
    #ifdef LED
        led_on(LED);  //if 1st string commented, we will get an error "undefined identifier"
    #endif
    

    No - if LED isn't defined then you will not get any "undefined identifier" from the compiler, because you will not get inside the #ifdef/#endif block - the preprocessor will clear away the contents of that block. So you'll end up with three very empty lines:

    
    
    
    

    And with LED defined to PA7, you end up with (assuming PA7 isn't also a #define)

    
        led_on(PA7);   <<<=== the preprocessor expansion of the LED define.
    
    

  • You are right about how preprocessor/compiler MUST do. And GCC gives such output, but not ARM. Have you tested? May be it is only my problem? Note this problem in .cpp file.

  • Have you ordered the compiler to just preprocess the data and looked at the output?

    Post the output from the preprocessor. If the output is wrong, then it's time to contact Keil support.

  • By the way - you haven't posted specific version information for your tool set.

    Lots of people are using the Keil tools.

    And lots of people are using conditional compilation.

    My code would fail badly if the preprocessor didn't do what it should - it doesn't with the versions I'm currently using. But I seldom jump onto the latest versions until I'm starting a new product. Existing products normally lives their whole life using the compiler that was used when the product was on beta testing. All to make sure that I can rebuild and get a binary-identical copy.

  • Have you tested?

    Have you?

    May be it is only my problem?

    Quite certainly it is.

    And instead of accusing others of playing "word games", how about you actually learn what those words mean, and how they might apply to your problem?

  • This worked fine in uV5.15, perhaps you need to use something more unique than LED, to ensure it's not defined someplace else, in an include, command line or something.

    I'd be very surprised if it were a compiler/preprocessor bug as it would break a whole galaxy of stuff.

    // Define test - led.cpp
    
    void led_test(void)
    {
    //#define LED  PA7
    
    #ifdef LED
        led_on(LED);  // no errors here when above define commented
    #endif
    }
    

  • The preprocessor output tends to be a good way to solve lots of slightly muddy assumptions about what data the tools are actually operating on. The reason all C/C++ compilers has a "preprocess only" option is the huge number of "doh" moments when people have spent hours with a problem and then finally look at the actual expansion.

    A compiler tool chain is normally run through a very large code base of tests as regression testing. This code base is not missing #define, #ifdef, #if defined, ... constructs.

    So when something slips through, it's normally very very special cases that somehow, somewhere deep down affects a coding assumption in the code optimizer. Or an incorrect understanding of the syntax might make the tools do what they shouldn't - but then these errors tends to be there from day one. Until someone finally has a test case and reports back about the failure.

    The standard #include files shipped with the compiler has lots of #define constructs, so it would most probably be impossible to build the MDK-ARM libraries if the preprocessor doesn't handle #define as expected.