Some confusion in following C logic

Discussion in 'Programmer's Corner' started by ep.hobbyiest, Jul 4, 2015.

  1. ep.hobbyiest

    Thread Starter Member

    Aug 26, 2014
    91
    0
    Hi
    When i was reading one of the c code i could not understand the following logic.
    Here is logic and where it is define the function

    Code (C):
    1.  
    2. in usb_device_hid.c file
    3.     extern void USB_DEVICE_HID_IDLE_RATE_CALLBACK(uint8_t reportId, uint8_t idleRate);
    4.  
    5. in usb_config.h file  
    6.     #define USB_DEVICE_HID_IDLE_RATE_CALLBACK APP_DeviceMouseIdleRateCallback
    7.  
    8.  
    9. in app_device_mouse.c
    10. void APP_DeviceMouseIdleRateCallback(uint8_t reportId, uint8_t idleRate)
    11. {
    12.     //Make sure the host is requesting to set the idleRate on a legal/implemented
    13.     //report ID.  In applications that don't implement report IDs (such as this
    14.     //firmware) the value should be == 0.
    15.     if(reportId == 0)
    16.     {
    17.         mouse.inputReport[reportId].idleRate = idleRate;
    18.     }
    19. }
    20.  
    21.  
    There is declaration for the function "APP_DeviceMouseIdleRateCallback"
    but later if is define by other name and used them.

    can any one explain me what is exactly done...
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,142
    1,790
    The #define statement is what we call a "text substitution" macro. It works on the input source file BEFORE the compiler actually looks at the input text. The usefulness of this approach is apparent when you want to change the name of something that is spread across several thousand files. You change the #define and you are done.
     
    ep.hobbyiest likes this.
  3. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,804
    833
    It is also useful to make a program more readable. Consider a table of values:
    Code (Text):
    1. #define Up 1
    2. #define Down 2
    3. #define Left 3
    4. #define Right 4
    Then later, the first statement code is easier to read than the second. Especially after coming back to the code after a while:
    Code (Text):
    1. If (Action == Up ) {
    2.     ....
    3.     }
    4.  
    5. If (Action == 1){
    6.     ....
    7.     }
     
    ep.hobbyiest likes this.
  4. WBahn

    Moderator

    Mar 31, 2012
    17,743
    4,795
    Basically what PapaBravo said. While I will add is that the #include statement that includes usb_config.h has to occur later (as seen by the preprocessor) than the one that includes usb_device_hid.h.

    What happens is the statement (actually the preprocessor directive)

    #define USB_DEVICE_HID_IDLE_RATE_CALLBACK APP_DeviceMouseIdleRateCallback

    is see and the text string "USB_DEVICE_HID_IDLE_RATE_CALLBACK" is associated with the text string "APP_DeviceMouseIdleRateCallback"

    After this point, whenever the preprocessor sees the first string (with come exceptions, such as within a string literal), it replaces that string with the second string. So when the compiler finally sees the prototype statement is usb_device_hid.h it has already been transformed from

    extern void USB_DEVICE_HID_IDLE_RATE_CALLBACK(uint8_t reportId, uint8_t idleRate);

    to

    extern void APP_DeviceMouseIdleRateCallback(uint8_t reportId, uint8_t idleRate);
     
    ep.hobbyiest likes this.
  5. flat5

    Active Member

    Nov 13, 2008
    403
    17
    I get tired of typing Serial.print so I tried
    #define sp Serial.print
    and
    sp("It works!");
    works.

    However I just realized to keep the code understandable it would be better to use 'sp( '
    and later search/replace 'sp(' with 'Serial.print(' and remove the #define.
     
    Last edited: Jul 11, 2015
  6. WBahn

    Moderator

    Mar 31, 2012
    17,743
    4,795
    Or you can make a parameterized macro

    #define sp(string)

    and use

    sp("It works!");

    Clearly declare your macros up top and the code is quite readable. Many of the standard library function you use are nothing more than parameterized macros.

    Doing a search and replace is VERY dangerous.

    What if you have someplace in your code

    x = FingerGrasp(y);

    It now becomes

    x = FingerGraSerial.print(y);
     
  7. flat5

    Active Member

    Nov 13, 2008
    403
    17
    Last edited: Jul 11, 2015
  8. WBahn

    Moderator

    Mar 31, 2012
    17,743
    4,795
    Still too dangerous an unwieldy. Try to adopt good and scalable code practices now -- would you really want to do 'search and replace' one at a time on code that was in a couple dozen files each with a thousand or more lines in it.
     
    theonewho likes this.
  9. flat5

    Active Member

    Nov 13, 2008
    403
    17
    I'll never have that problem. Hobbyist is my middle name.
    I'm 67 and a slow learner. I have written a thousand lines though :)
    It's on this forum.
     
  10. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    It doesn't work that way. Only whole words get replaced.
     
  11. theonewho

    New Member

    Jul 9, 2015
    17
    2
    It does work that way actually -- at least it can work that way.

    You've assumed that you know exactly how this user has his editor set up and that he has the "whole words" option selected for the text search functionality. Matching whole words only during text search is, in my experience, invariably an option that may or may not be selected by default in an editor.

    Not picking on you btw. @WBahn assumed that whole words would be turned off. He would have been better served to say that such a thing could happen and he wouldn't have been wrong. Best practices, ftw, even for hobbyists.
     
    Last edited: Jul 12, 2015
  12. WBahn

    Moderator

    Mar 31, 2012
    17,743
    4,795
    It doesn't? I don't recall him saying what editor he was using? What did I miss?

    Depends entirely on the editor being used and which options are chosen for the search. Also, if it is set up for whole words only, then (again depending on the editor) it won't see "sp(" in sp(x) as a whole word and wouldn't replace anything at all. So either way it's not a good approach.
     
  13. flat5

    Active Member

    Nov 13, 2008
    403
    17
    The search works perfect in the Arduino 'IDE'.
    Chose 'seO' from 'morseOutput'. Happened to find about twenty and nothing else.
    search test.jpg
     
  14. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    Why editor should matter? This is a C pre-processor:

    Code (C):
    1. #define sp Serial.print
    2. sp("It works!"); // macro from #define expanded - it changes to Serial.print("It wprks!")
    3. grasp("It does not work!"); //#define has no effect - will not change to graSerial.print("It does not work!");
     
  15. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,804
    833
    It matters because the discussion is about NOT using the pre-processor. The TS wants to use an editor.
     
  16. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    Sorry, totally my fault.
     
  17. WBahn

    Moderator

    Mar 31, 2012
    17,743
    4,795
    Which means that you will have the potential problem that I described.
     
Loading...