Friday, August 29, 2014

macro vs inline

why inline:
-----------------
In many programming languages, it is quite common to cluster the program code into several functions. This improves the readability of the code and allows an easy reusage of code snippets. However, one downside of clustering code into multiple functions is, that each function call takes some extra time: the processor needs to allocate space on the stack, save the return address and put the parameters onto the stack.

how to overcome this downside:

- inline keyword
- By using the inline-keyword on a function, the developer gives a hint to the compiler, to substitute all invocation of this function. 
- As the inline keyword is just a suggestion to the compiler, the compiler can accept or ignore this hint.

- To save the time of an extra function call, the compiler has the opportunity to substitute any function call with the called functions body(i.e. using the inline keyword). As it would be very inefficient to substitute every function call, the compiler only substitutes well-chosen functions.If the function is to big, it may be inefficient to substitute it, as there aren’t enough registers in the CPU to handle all variables simultaneously.

- The difference between an inline function and a regular function is that wherever the compiler finds a call to an inline function, it writes a copy of the compiled function definition. However, with a regular function, a normal function call is generated.

- how inline is getting expanded:

Listing 4.1: add is a inlinable function

1 inline static int add (int s1 , int s2 )
2 {
3 return s1 + s2 ;
4 }
5

6 int some_function (int a , int b )
7 {
8 return add (a , b ) ;
9 }


Listing 4.2: The resulting some_function-function after substitution
1 int some_function (int a , int b )
2 {
3 return a + b ;   <================  inline function body has expanded
4 }

in which cases we have to use the inline:
-. In most cases, this are small and often called functions.

Limitation in the inline:
1) First, recursive functions can not be embedded. It is not possible to nest all possible function calls, as the depth of the stack trace depends on parameters and is unknown at compile time.

2) As a second limitation, functions with external linkage should not use private variables, that are only visible in the current translation unit. These variables are no longer accessible, when the function is embedded in another translation unit. This may not be a problem with gcc, as the gcc compiler only substitutes functions, that are called in the same translation unit in which they were defined.

 Forcing the compiler to inline a function
- this is the compiler providing options

Listing 4.5: Forcing a specific inline behavior with gcc

1 inline __attribute__ (( always_inline )) int
,→ inline_function (int a , int b ) ;

2 inline __attribute__ (( noinline ) ) int no_inline_function ( int

,→ a , int b ) ;

Best reference: https://wr.informatik.uni-hamburg.de/_media/teaching/wintersemester_2013_2014/epc-1314-fasselt-c-keywords-report.pdf

inline vs macro

1. Inline follows strict parameter type checking, macros do not.
2. Macros are always expanded by preprocessor, whereas compiler may or may not replace the inline definitions.(because compile may do inline or will not do inline)
3. he fact that macros use text replacement creates the potential for bugs. Suppose we have the following 
code:
3a. #define DOUBLE(X) X*X
 int y = 3;
 int j = DOUBLE(++y);


If you’re expecting that j will be assigned a value of 4 squared (16), then you would be wrong. Because of the text replacement, what actually happens is that the DOUBLE(++y) expands to ++y * ++y, which equals 4*5, giving us 20. This problem would not occur if DOUBLE were implemented as an inline function. 

3b: 
#define ADD_TWO(x,y) x += 2; y +=2

bool flag = true;
int j = 5, k = 7;


if(flag)
 ADD_TWO(j,k);
Then you’re probably thinking that the macro will expand to this:
if(flag)
{
 j +=2;
 k +=2; 
} 
But what actually happens is that the if statement binds to the first expression in the macro. So this is what it really expands to:
if(flag)
{
 j +=2;
}  
 
k +=2;


refer : https://www.programmerinterview.com/index.php/c-cplusplus/inline-vs-macro/

From first look the output seems to be 1, but it produces 36 as output.
#define square(x) x*x
int main()
{
  int x = 36/square(6); // Expended as 36/6*6
  printf("%d", x);
  return 0;
}
// Output: 36
If we use inline functions, we get the expected output. Also the program given in point 4 above can be corrected using inline functions.
inline int square(int x) { return x*x; }
int main()
{
  int x = 36/square(6);
  printf("%d", x);
  return 0;
}
// Output: 1


bottom line: macro is just text replacement . but the inline is substituting the function

No comments:

Post a Comment