Knowledge is Power.

  • Who you are ?

    Working on machines without understanding them ? Then you should be here..

  • Where you are ?

    Geographical location should not become a barrier to Share our knowledge.

  • What do you do ?

    Puzzles and Interview question are intended to be discussed here.

    Sunday, March 28, 2010

    Namespaces

    Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name.

    The format of namespaces is:


    namespace identifier
    {
    entities
    }


    Where identifier is any valid identifier and entities is the set of classes, objects and functions that are included within the namespace. For example:

    1
    2
    3
    4
    namespace myNamespace
    {
    int a, b;
    }


    In this case, the variables a and b are normal variables declared within a namespace called myNamespace. In order to access these variables from outside the myNamespace namespace we have to use the scope operator ::. For example, to access the previous variables from outside myNamespace we can write:

    1
    2
    myNamespace::a
    myNamespace::b


    The functionality of namespaces is especially useful in the case that there is a possibility that a global object or function uses the same identifier as another one, causing redefinition errors. For example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // namespaces
    #include
    using namespace std;

    namespace first
    {
    int var = 5;
    }

    namespace second
    {
    double var = 3.1416;
    }

    int main () {
    cout << first::var << endl;
    cout << second::var << endl;
    return 0;
    }


    5
    3.1416

    In this case, there are two global variables with the same name: var. One is defined within the namespace first and the other one in second. No redefinition errors happen thanks to namespaces.

    using

    The keyword using is used to introduce a name from a namespace into the current declarative region. For example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // using
    #include
    using namespace std;

    namespace first
    {
    int x = 5;
    int y = 10;
    }

    namespace second
    {
    double x = 3.1416;
    double y = 2.7183;
    }

    int main () {
    using first::x;
    using second::y;
    cout << x << endl;
    cout << y << endl;
    cout << first::y << endl;
    cout << second::x << endl;
    return 0;
    }


    5
    2.7183
    10
    3.1416

    Notice how in this code, x (without any name qualifier) refers to first::x whereas y refers to second::y, exactly as our using declarations have specified. We still have access to first::y and second::x using their fully qualified names.

    The keyword using can also be used as a directive to introduce an entire namespace:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // using
    #include
    using namespace std;

    namespace first
    {
    int x = 5;
    int y = 10;
    }

    namespace second
    {
    double x = 3.1416;
    double y = 2.7183;
    }

    int main () {
    using namespace first;
    cout << x << endl;
    cout << y << endl;
    cout << second::x << endl;
    cout << second::y << endl;
    return 0;
    }


    5
    10
    3.1416
    2.7183

    In this case, since we have declared that we were using namespace first, all direct uses of x and y without name qualifiers were referring to their declarations in namespace first.

    using and using namespace have validity only in the same block in which they are stated or in the entire code if they are used directly in the global scope. For example, if we had the intention to first use the objects of one namespace and then those of another one, we could do something like:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // using namespace example
    #include
    using namespace std;

    namespace first
    {
    int x = 5;
    }

    namespace second
    {
    double x = 3.1416;
    }

    int main () {
    {
    using namespace first;
    cout << x << endl;
    }
    {
    using namespace second;
    cout << x << endl;
    }
    return 0;
    }


    5
    3.1416

    Namespace alias


    We can declare alternate names for existing namespaces according to the following format:


    namespace new_name = current_name;


    Namespace std

    All the files in the C++ standard library declare all of its entities within the std namespace. That is why we have generally included the using namespace std; statement in all programs that used any entity defined in iostream.

    Monday, March 8, 2010

    • The C preprocessor is a program that processes our source program before it is passed to the compiler.
    • preprocessor is a separate program which transforms C source code containing preprocessor directives into source code with the directives removed.
    • The preprocessor is implemented as an integral part of an Standard C compiler.
    • gcc -E filename will show the preprocessed file.
    • Preprocessor commands are known as directives.
    • Preprocessor works on a line by line basis.
    • The preprocessor doesn't know about the scope rules of C. Preprocessor directives like #define take effect as soon as they are seen and remain in effect until the end of the file that contains them
    Preprocessor Directives:

    • The preprocessor commands are called as directives.
    • Each of these preprocessor directives begin with a # symbol.
    • The directives can be placed anywhere in a program but they are most often placed at the beginning of a program.
    • The preprocessor directives are classified in to 4 major categories

      1. Macro Expansion(#define)
      2. File Inclusion(#include)
      3. Conditional Compilation
      4. Miscellaneous directives
    • The 2 most frequently used features are #include,to include the contents of a file during compilation and #define ,to replace a token by an arbitrary sequence of characters.
    1.Macro Expansion:

    * C preprocessor provides a facility for defining constant and substitution,which are commonly called macros.
    * Macros are used when we want to make a program more readable or when we dont have enough information about certain values.
    * A macro definition has the form
    #define name replacement text
    * The statement above define a macro and some replacement text.The preprocessor will replace the name with the replacement text whenever the name is ocur in the source file.
    * The preprocessor directives are not C statements, so they do not end with semicolons.
    * Eg:
    #include
    #define currency_rate 51
    int main()
    {
    int rs,money=500;
    rs=money * currency_rate;
    printf("RS=%d\n",rs);
    return 0;
    }
    So if the currency rate is changed we can make the necessary change inonly one place.
    * Any name may be defined with any replacement text.
    Eg
    #define forinfinite for(;;)
    defines a new word forinfinite for an infinite loop
    * A #define directive can be used to replace an operators or condition or even a entire statement
    Eg
    1.#define AND &&
    2.#define condition (a>25 AND a<50)>


    2.File Inclusion(#include):

    * This directive allow one file to be included in another file.
    * Syntax is #include "file name"
    This will insert the entire content of filename in to the source code.
    * It can be used in 2 cases

    1. If the program is very large then the code is divided in to several different files.These files are #included at the begining of main program file.
    2. Some functions or some macros are almost needed in all programs. These functions and macros are stored in a file and included in the program that are needed Eg header files
    * #include statement can be written in 2 ways

    1. #include "filename"
    2. #include <>
    * #include "filename.c" would look for the file filename.c in the current directory as well as the specified list of directories as mentioned in the include search path.
    * #include <> would look for the file filename.c in the specified list of directories only.

    3.Conditional Inclusion

    * It is possible to control preprocessing itself with conditional statements that are evaluated during preprocessing.
    * provides a way to include code selectively depending on the condition.
    * Some of the conditional directives are
    1. #if
    2. #elif
    3. #else
    4. #endif
    5. #ifdef
    6. #ifndef
    7. #undef

    1. #if directive

    * #if can be used to test whether an expression evaluates to a nonzero value or not.(the expression may not include sizeof,casts or enum constants)
    * The generalized form of the if directive is
    #if <>
    #endif
    * If the result of the expression is nonzero then subsequent lines upto #endif are compiled otherwise they are skipped.
    * example code to make sure that the contents of the file hdr.h are included only once
    #if !defined(HDR)
    #define HDR
    /* contents of hdr.h */
    #endif
    * The defined() predicate returns true if the symbol is defined otherwise it is false.
    2. #else directive

    * #else always comes with #if directive
    * It allow us to specify the action if the condition is not true
    * Eg: Suppose we have 3 files
    file1.h
    #define USD 1
    file2.h
    #define UKP 1
    file3
    #include <>
    #include <>
    #if(defined(USD))
    #define rate 46
    #else
    #define rate 100
    #endif
    since USD is defined in file1.h,the currency rate is taken as 46.
    3. #elif directive

    * #elif allow us to take one action if there are multiple decision points.
    * #elif is similar to #else but it is followed by a condition.
    * Example: The following sequence tests the name SYSTEM to decide which version of a header to include

    #if SYSTEM == SYSV
    #define HDR "sysv.h"
    #elif SYSTEM == BSD
    #define HDR "bsd.h"
    #elif SYSTEM == MSDOS
    #define HDR "msdos.h"
    #else
    #define HDR "default.h"
    #endif
    #include HDR
    4. #ifdef directive

    * The ifdef directive makes substitution based on whether a particular identifier is defined.
    * If the identifier is defined,it returns true,otherwise it is false.
    * Eg: Suppose we have 3 files
    file1.h
    #define USD 1
    file2.h
    #define UKP 1
    file3
    #include <>
    #include <>
    #ifdef USD
    #define rate 46
    #endif
    #ifdef UKP
    #define rate 100
    #endif
    The 1st ifdef directive checks whether the identifier USD is defined. since it is defined in file1.h the condition is true and the rate is defined as 46. The 2nd ifdef directive checks whether the identifier UKP is defined.Since file2.h is not included it is not defined so the condition is false and the directive is not processed.
    If instead of file1.h, if file2.h is included then the rate will be 100
    5. #ifndef directive

    * #ifndef (means 'if not defined') works exactly opposite to #ifdef.
    * #ifndef is compleement of #ifdef. so when #ifdef returns true,#ifndef returns false
    * Eg: Suppose a function fun() is defined in a file 'file1.h'.and file1.h is #included in file2.h.now if we #include both 'file1.h' and 'file2.h' then the compiler flashes an error 'multiple declaration for fun'.To avoid this we can write the following code in the header file
    /*file1.h*/
    #ifndef file_h
    #define file_h
    fun()
    {
    /*code*/
    }
    #endif
    * first time the file 'file.h' gets included the preprocessor checks whether a macro called file_h has been defined or not.first time its not defined so the macro gets defined and the fun() get included.Next time we attempt to include the same file.the macro file_h already defined so the fun() is not included.
    6. #undef directive

    * #undef nullify the effect of the #define directive and specify a new value.
    * Ex:
    #include <>
    #define SUM 40
    #undef SUM
    #define SUM 100
    int main()
    {
    printf("SUM=%d\n",SUM);
    }
    The 1st #define assign SUM as value 40 but the #undef indicate that the SUM definition no longer exist. The 2nd #define define SUM as 100. so the program will print the output as SUM=100.

    4.Miscellaneous Directives

    * There are 3 more preprocessor directives available but they are not very commonly used

    1. #pragma
    2. #error
    3. #line

    1.#pragma directive:

    * #pragma is a special purpose directive that can use to turn on or off certain features
    * pragmas vary from one compiler to another.

    1. #pragma startup and #pragma exit: These directives allow us to specify functions that are called upon program startup(before main()) or program exit(just before the program terminates)
    Ex:
    void myfun1();
    void myfun2();
    #pragma startup myfun1
    #pragma exit myfun2
    int main()
    {
    printf("I am in main\n");
    return 0;
    }
    void myfun1()
    {
    printf("I am in myfunction1");
    }
    void myfun2()
    {
    printf("I am in myfunction2");
    }
    Output
    I am in myfunction1
    I am in main
    I am in myfunction2
    Note1.The functions myfun1() and myfun2() will not receieve or return any value.
    2.If we want 2 functions to executed at startup then thier pragmas should be defined in the reverse order in which we want to call them
    2. #pragma warn: This directive tells the compiler whether or not we want to suppress a specific warning
    Eg:
    #pragma warn -rvl /*return value */
    #pragma warn -par /*parameter not used*/
    #pragma warn -rch /*unreachable code*/
    int fun1()
    {
    printf("I am in function1");
    }
    void fun2(int a)
    {
    printf("I am in function2");
    }
    int fun3()
    {
    int z=10;
    return z;
    z++;
    }
    int main()
    {
    fun1();
    fun2(100);
    fun3();
    return 0;
    }
    In the above example the function fun1() doesnt return a value. The parameter passed to the fun2() is not being used in fun2() and the control will never reach z++ in fun3()
    If we compile the program we should expect warnings indicating the above problem.
    But the program does not produce warnings because we have suppressed the warnings using #pragma.
    If we replace the '-' sign with the '+' sign in #pragma then the warnings will be shown in the compilation.

    3.#error directive:

    * The error directive is used to specify an error message for a specific situation
    * The error message is generated by the preprocessor
    * Eg:Suppose we have 3 files
    file1.h
    #define USD 1
    file2.h
    #define UKP 1
    file3
    #include <>
    #include <>
    #if !defined(USD) || !defined(UKP)
    #error "ERROR: NO_CURRENCY rate is specified"
    #endif
    #if checks whether USD or UKP is defined.If both are not defined then the preprocessor displays an error

    4. #line Directive:

    * The #line directive allows us to define arbitrary line numbers for the source lines.
    * Normally the compiler counts lines starting at line number 1.using the #line directive,we can specify an arbitrary line number at any point.The compiler then uses that line number for subsequent counts.
    * #line is used to indicate line numbers which can be used for debugging
    * Eg:
    int main()
    {
    fun1();
    #line100
    fun2(100);
    printf("C FILE %s LINE %d\n",_FILE_,_LINE_);
    #line200
    fun3();
    return 0;
    }
    after fun1() the line number is assigned to 100. so fun2(100); is at line number 101 and then line number is modified to 200 before fun3();. so fun3(); is at line number 201.
    * _FILE_ and _LINE_ are the 2 special identifiers.Which indicate the file name of the source file and the current line number
    Operators in Preprocessor:

    * The 2 operators used in the preprocessor are

    1. #
    2. ##

    1.# operator:

    * If the macros are present with in the quoted strings it is not replaced by the #defined macro.
    * But if the macroname is preceded by a # then the macro is expanded into a quoted string with the parameter replaced by the actual argument
    * Eg:
    #include
    #define toprint(expr) printf(#expr "=%d\n",expr)
    int main()
    {
    int x=10,y=5;
    toprint(x/y);
    return 0;
    }
    when toprint(x/y);is invoked the macro is expanded in to
    printf("x/y" "=%d\n",x/y);
    and the strings are concatenated.so the statement becomes
    printf("x/y=%d\n",x/y);
    The output of the above program is x/y=2
    * In the above example instead of #expr if only expr is present like
    #define toprint(expr) printf("expr=%d\n",expr) then the output is expr=2

    2.## operator:

    * The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion.
    * If a parameter in the repacement text is adjacent to a ##, the parameter is replaced by the actual argument,the ## and surrounding white space are removed,and the result is rescanned
    * Example The macro Join concatenates its two arguments
    #define Join(front,back) front##back
    now Join(hello,100) resuts hello100.

    NULL Directive

    * #
    * A preprocessor line of the form # has no effect
    * if the line has only #symbol the preprocessor ignores the line
    1.What is the output of the following program?
    #include
    #define clrscr() 10
    int main()
    {
    printf("result=%d\n",clrscr());
    return 0;
    }


    result=10
    #defines are used for textual replacement
    2.What is the output of the following program?
    #include
    #define fun(f1,f2) f1##f2
    int main()
    {
    int some100=100;
    printf("result=%d\n",fun(some,100));
    return 0;
    }
    Solution

    result=100
    To know about the ## operator Click here

    3.What is the output of the following program?
    #include
    #define FALSE -1
    #define TRUE 1
    #define NULL 0
    int main()
    {
    if(NULL)
    puts("NULL\n");
    else if(FALSE)
    puts("FALSE\n");
    else
    puts("TRUE\n");
    return 0;
    }
    Solution

    FALSE
    Preprocessor doesnt replace the vaues given inside the double quotes.The check by if condition is boolean value false. so it goes to else if part.-1 is boolean value true. hence it prints FALSE.
    4.What is the output of the following program?
    #include
    #define max 5
    #define int arr1[max]
    main()
    {
    typedef char arr2[max];
    arr1 list={0,1,2,3,4};
    arr2 name="name";
    printf("%d %s\n",list[0],name);
    return 0;
    }
    Solution

    Compier Error :arr1 undeclared
    arr2 is decared of ype array of size 5 of characters.so it can be used to declare the variable name of the type arr2.But it is not the case of arr1.Hence an error.
    #defines are used for textual replacement whereas typedefs are used for declaring new types.

    5.What is the output of the following program?
    #include
    #define int char
    main()
    {
    int i=65;
    printf("sizeof(i)=%d \n",sizeof(i));
    return 0;
    }
    Solution

    sizeof(i)=1
    #define replaces the string int by the macro char.The size of char is 1 byte

    6.What is the output of the following program?
    #include
    #define assert(cond) if(!(cond))\
    printf("assertion failed for condition %s\n",#cond)
    main()
    {
    int x=100;
    if(x==100)
    assert(x<100);
    else
    printf("No assert call\n");
    return 0;
    }
    Solution
    assertion failed for condition x<100


    7.What is the output of the following program?
    #include
    #define assert(cond) if(!(cond))\
    printf("assertion failed for condition %s\n",#cond)
    main()
    {
    int x=100;
    if(x==0)
    assert(x<100);
    else
    printf("No assert call\n");
    return 0;
    }
    Solution
    No output
    The else part in which the printf is there becomes the else for if in the assert macro.Hence nothing is printed.The solution is to use conditional operator instead of if statement.#define assert(cond) ((cond)?(0):printf(""))


    8.What is the output of the following Program?
    #include
    #define string_def char*
    main()
    {
    typedef char* string_type;
    string_type s1="My",s2="name";
    string_def s3="is",s4="Suni";
    printf("%s %s %s %s\n",s1,s2,s3,s4);
    return 0;
    }
    Solution
    Segmentation Fault
    The preprocessor output is
    main()
    {
    typedef char* string_type;
    string_type s1="My",s2="name";
    char* s3="is",s4="Suni";
    printf("%s %s %s %s\n",s1,s2,s3,s4);
    return 0;
    }
    s4 is of type char not char* so printing s4 as a string produce segmentation fault.

    9.What is the output of the following program?
    #include
    #define DEF(array,type) sizeof(array)/sizeof(type)
    main()
    {
    int arr[10];
    printf("Total number of array elements=%d",DEF(arr,int));
    return 0;
    }
    Solution
    Total number of array elements=10
    The size of integer array of 10 elements is 10*sizeof(int).The macro expands to sizeof(arr)/sizeof(int)=>10*sizeof(int)/sizeof(int).So the answer is 10


    10.What is the output of the following Program?
    #include
    #define max main()
    main()
    {
    max;
    printf("Hello Welcome\n");
    return 0;
    }

    1. Compilation error
    2. Preprocessing error
    3. runtime error
    4. executes until the stack overflows

    Solution
    4.executes until the stack overflows