Wednesday, June 12, 2013

Article 2: Macro VS Inline Function.

Article 2: Macro VS Inline Function. There can be ‘n’ number of cases where macro will fail. I will try to demonstrate few of them.

#define MIN_VERSION_1(a,b) a < b ? a : b
#define MIN_VERSION_2(a,b) (a) < (b) ? (a) : (b)
#define MIN_VERSION_3(a,b) ( (a) < (b) ? (a) : (b) )

inline int min_function(int a ,int b)
{
    return ( a < b ? a : b );
}

All the use cases will be checked on the above code snippet.
Consideration:
1. Let’s consider we have two variables with name a,b and we have to find min from them.
int a = 10;
int b = 20;
int min = 0;
2. I have created one method to print the result in little good manner, you can write your own. The function is written in just for formatted output.
#define MAX_STRING_LENGTH 45
#define WIDTH 4
void printResult(const char* useCase, int a, int b,int min, bool pass)
{
    std::cout<<"\n";
    std::cout<<" | "<<useCase;
    // Extra padding for good output.
    int lk = std::strlen(useCase);
    for(int i = 0 ; i < abs(MAX_STRING_LENGTH - std::strlen(useCase)); i++)
    {
        std::cout<<" ";
    }
    std::cout<<std::setw(WIDTH)<<" | " <<a;
    std::cout<<std::setw(WIDTH)<<" | " <<b;
    std::cout<<std::setw(WIDTH)<<" | " <<min;
    std::cout<<std::setw(WIDTH)<<" | " <<( pass ? " PASS  | " :" FAIL  | ");
}

void printResult(const char* useCase, const char* a, const char* b,const char* min, const char* result)
{
    std::cout<<"\n";
    std::cout<<" | "<<useCase;
    // Extra padding for good output.
    int lk = std::strlen(useCase);
    for(int i = 0 ; i < abs(MAX_STRING_LENGTH - std::strlen(useCase)); i++)
    {
        std::cout<<" ";
    }
    std::cout<<std::setw(WIDTH)<<" | " <<a;
    std::cout<<std::setw(WIDTH)<<" | " <<b;
    std::cout<<std::setw(WIDTH)<<" | " <<min;
    std::cout<<std::setw(WIDTH - 1)<<" | " <<result;
}

3. A function is created for resetting the values to default values:
void resetValues(int&a, int&b, int &min)
{
    a = 10;
    b = 20;
    min = 0;
}

Case 1:
    std::cout<<"\n\n------------------------------------------------";
    std::cout<<"\n\t\tFinding output for min( a, b)";
    std::cout<<"\n--------------------------------------------------";
    printResult("Use Case","a ","b ","min","Result |");
    std::cout<<"\n--------------------------------------------------";
    resetValues(a,b,min);
    min = min_function(a ,b);
    printResult("Expected",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_1(a ,b);
    printResult("MIN_VERSION_1(a,b) a < b ? a : b",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_2(a ,b);
    printResult("MIN_VERSION_2(a,b) (a) < (b) ? (a) : (b)",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_3(a ,b);
    printResult("MIN_VERSION_3(a,b) ( (a) < (b) ? (a) : (b) )",a,b,min,1);

Output:





Case 2:
    std::cout<<"\n\n------------------------------------------------";
    std::cout<<"\n\t\tFinding output for min( a += 3, b)";
    std::cout<<"\n--------------------------------------------------";
    printResult("Use Case","a ","b ","min","Result |");
    std::cout<<"\n--------------------------------------------------";
    resetValues(a,b,min);
    min = min_function(a +=3 ,b);
    printResult("Expected",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_1(a +=3 ,b);
    printResult("MIN_VERSION_1(a,b) a < b ? a : b",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_2(a +=3 ,b);
    printResult("MIN_VERSION_2(a,b) (a) < (b) ? (a) : (b)",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_3(a +=3 ,b);
    printResult("MIN_VERSION_3(a,b) ( (a) < (b) ? (a) : (b) )",a,b,min,0);

Output:













Case 3:
    std::cout<<"\n\n------------------------------------------------";
    std::cout<<"\n\t\tFinding output for min( a , b) + 25";
    std::cout<<"\n--------------------------------------------------";
    printResult("Use Case","a ","b ","min","Result |");
    std::cout<<"\n--------------------------------------------------";
    resetValues(a,b,min);
    min = min_function(a ,b) + 25;
    printResult("Expected",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_1(a ,b) + 25;
    printResult("MIN_VERSION_1(a,b) a < b ? a : b",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_2(a ,b) + 25;
    printResult("MIN_VERSION_2(a,b) (a) < (b) ? (a) : (b)",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_3(a ,b) + 25;
    printResult("MIN_VERSION_3(a,b) ( (a) < (b) ? (a) : (b) )",a,b,min,1);

Output:





Case 4:
    std::cout<<"\n\n------------------------------------------------";
    std::cout<<"\n\t\tFinding output for min( ++a , b)";
    std::cout<<"\n--------------------------------------------------";
    printResult("Use Case","a ","b ","min","Result |");
    std::cout<<"\n--------------------------------------------------";
    resetValues(a,b,min);
    min = min_function( ++a , b);
    printResult("Expected",a,b,min,1);

    resetValues(a,b,min);
    min = MIN_VERSION_1( ++a , b);
    printResult("MIN_VERSION_1(a,b) a < b ? a : b",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_2( ++a , b);
    printResult("MIN_VERSION_2(a,b) (a) < (b) ? (a) : (b)",a,b,min,0);

    resetValues(a,b,min);
    min = MIN_VERSION_3( ++a , b);
    printResult("MIN_VERSION_3(a,b) ( (a) < (b) ? (a) : (b) )",a,b,min,0);

Output:


Tuesday, June 4, 2013

Article 1: Implicit Conversion for const and non-const reference.

#include <iostream>

/*

*Problem:     
Implicit conversion will not work for non const reference.
*Description:
Read the comments above each method call.
*Proof:     
Print address of each variable which is passed as an argument, the address will be same for foo2(), foo3() but will be different for foo1(),and foo() will not be called anyways(compilation error)
*/



void foo(const double& f)
{
    std::cout<<"\nConst Reference Function called. "<<&f;
}

void foo1(double& f)
{
    std::cout<<"\nNormal Reference Function called "<<f;
}

void foo2(int& i)
{
    std::cout<<"\nNormal Reference Function called for int. "<<&i;
}

void foo3(const int& i)
{
    std::cout<<"\nConst Reference Function called for int. "<<&i;
}

int main()
{
    int i = 10;
    std::cout<<"\nInitial Address of i "<<&i;
    // This will work as i local copy will be created as double and that can be access as a const value.
    foo(i);
   
    // This function will give an error as if it create a local variable double which is passed as reference,
    // it shows that this method can change the value, which is not possible.
    // error C2664: 'foo1' : cannot convert parameter 1 from 'int' to 'double &'
    foo1(i);

    // This is called without any issue.
    foo2(i);

    // This is called without any issue.
    foo3(i);
    std::cout<<"\n";
   

}
Output:
Initial Address of i 0025FE9C
Const Reference Function called. 0025FDCC
Normal Reference Function called for int. 0025FE9C
Const Reference Function called for int. 0025FE9C