Some confusion in following C logic

Thread Starter

ep.hobbyiest

Joined Aug 26, 2014
201
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

C:
in usb_device_hid.c file
    extern void USB_DEVICE_HID_IDLE_RATE_CALLBACK(uint8_t reportId, uint8_t idleRate);

in usb_config.h file   
    #define USB_DEVICE_HID_IDLE_RATE_CALLBACK APP_DeviceMouseIdleRateCallback
  
  
in app_device_mouse.c
void APP_DeviceMouseIdleRateCallback(uint8_t reportId, uint8_t idleRate)
{
    //Make sure the host is requesting to set the idleRate on a legal/implemented
    //report ID.  In applications that don't implement report IDs (such as this
    //firmware) the value should be == 0.
    if(reportId == 0)
    {
        mouse.inputReport[reportId].idleRate = idleRate;
    }
}
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...
 

Papabravo

Joined Feb 24, 2006
21,157
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.
 

djsfantasi

Joined Apr 11, 2010
9,156
It is also useful to make a program more readable. Consider a table of values:
Code:
#define Up 1
#define Down 2
#define Left 3
#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:
If (Action == Up ) {
    ....
    }

If (Action == 1){
    ....
    }
 

WBahn

Joined Mar 31, 2012
29,976
Hi
When i was reading one of the c code i could not understand the following logic.

<snip>

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...
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);
 

flat5

Joined Nov 13, 2008
403
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:

WBahn

Joined Mar 31, 2012
29,976
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.
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);
 

WBahn

Joined Mar 31, 2012
29,976
True. I would check each. 'Replace & find'. Much safer.
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.
 

flat5

Joined Nov 13, 2008
403
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.
 

theonewho

Joined Jul 9, 2015
17
It doesn't work that way. Only whole words get replaced.
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:

WBahn

Joined Mar 31, 2012
29,976
It doesn't work that way. Only whole words get replaced.
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.
 

flat5

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

NorthGuy

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

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

djsfantasi

Joined Apr 11, 2010
9,156
Why editor should matter? This is a C pre-processor:

C:
#define sp Serial.print
sp("It works!"); // macro from #define expanded - it changes to Serial.print("It wprks!")
grasp("It does not work!"); //#define has no effect - will not change to graSerial.print("It does not work!");
It matters because the discussion is about NOT using the pre-processor. The TS wants to use an editor.
 
Top