C/C++ FAQ

From CDOT Wiki
Revision as of 13:14, 30 October 2012 by Kirill Sochnev (talk | contribs)
Jump to: navigation, search

C/C++ FAQ

Q: Why is the postfix increment/decrement operator (e.g. a++ and a--) evaluated
   differently on different compilers?
Q: Why is the postfix increment/decrement operator (e.g. a++ and a--) evaluated
   differently on different compilers?
Q: When we define a function-like macro, does the compiler ignore or take into
   consideration the spaces in between the parentheses?
Q: When using square-bracket pointer arithmetic, does ptr[-k] decrement the pointer?
Q: Is this syntax for pointer casting and dereferencing *(int*)p for void* p equivalent
   to (*(int*)p)?
Q: Why can't void* variables be dereferenced?
Q: Can a functional pointer be used to point to an overloaded function? If so, which
   function will it call when the pointer is dereferenced and why?
Q: How to redirect  cerr to  a file (instead of a console window)?


A: The evaluation of expressions, especially arithmetic expressions are based on sequence points which are undefined by the language. Arithmetic expressions containing complex postfix calculations are evaluated differently across different compilers because each compiler is unequally efficient. That is to say, these expressions are not portable as each compiler uses a different way to evaluate the expression based on its efficiency implementation. This can be noted by observing the process time of an expression across different platforms, which will be different for the same expression, due to different methods of evaluation.

  • Q: Where is the source of your information regarding sequence points and implementations used by different compilers? (pliu)

For example, consider the following snippet:

   #include <iostream>
   using namespace std;

   #define PI 3.14

   int main()
   {
        double a = 2.35;
        cout << PI * ((a++) * (a++))<< endl;                              
        return 0;
   }

The GNU compiler prints 17.3407 as the output whereas the Borland compiler prints 24.7197 as the output.


Submitted by: Gideon Thomas and Marie Karimizadeh



Q: When we define a function-like macro, does the compiler ignore or take into consideration the spaces in between the parentheses?
For example:

#define F( x ) ((x) + (x))
int main()
{
   int a = 5;
   cout << F( a );
   return 0;
}

Which one of the following will the cout statement change to and why:

  1. cout << ((a) + (a));
  2. cout << x ) ((x) + (x)) a);

Note: in the second case, F( is considered the symbolic constant and is replaces by the rest of the string i.e. x ) ((x) + (x)) wherever it occurs.

A: cout << ((a) + (a)) will be executed. Although the compiler differentiates the symbolic constant from its value based on the position of the whitespace, ( tells it that it is a functional definition. #define follow the same identifier naming rules as variables do. Hence, ( cannot be included in the symbolic constant name and so the symbolic constant cannot be F(. Therefore, the compiler interprets this as a functional directive.


Submitted by: Gideon Thomas and Marie Karimizadeh



Q: When using square-bracket pointer arithmetic, does ptr[-k] decrement the pointer?
A: Yes. 'ptr' is the address of an element of the array; the array's element size is multiplied by the value of 'k', negated by '-', and then added to the address stored in 'ptr'. ptr[-k] moves to the element 'k' elements earlier than the element pointed to by ptr.


Submitted by: Kevin Kofler and Lucas Passarella, Team 9



Q: Is this syntax for pointer casting and dereferencing *(int*)p for void* p equivalent to (*(int*)p)?
A: Yes, however the latter is generally more accepted due to readability.
Submitted by: Team 6


Q: Why can't void* variables be dereferenced?
A: The pointer can't be dereferenced, because the compiler will not know how much of the memory is devoted to that particular value. For example if one has 8 bytes in memory with values in it, they are interpreted differently as int (2x 4 byte ints) and double (1x 8byte double). Without a data type the value cannot be determined therefore casting must be done first.
Submitted by: Team 6 (BTP300B)



Q: Can a functional pointer be used to point to an overloaded function? If so, which function will it call when the pointer is dereferenced and why?
Question Submitted by: Gideon Thomas and Marie Karimizadeh

A:Function Pointer can be used to point to any function with the same signature as its own.
"Signature is the information about a function that participates in overload resolution: its parameter-type-list... Function signatures do not include return type, because that does not participate in overload resolution." (Working Draft, Standard for Programming Language C++ 2005-10-19, p3, 1.3.11 signature)
In the case of overloaded functions the only thing they have in common is the name. Signatures are different, hence the same pointer to function can't be used for both of them.

Back to your question. Call to Function Pointer will call an overloaded function with the same signature as the Function Pointer.
Answer Submitted by: Team42

Q: How to redirect cerr to a file (instead of a console window)?
A:Use the rdbuf( ) method. [1]


Q: How to visualise a multi dimensional array?
A:

The simplest way to do so for a 2 dimensional array is a table

0123
4567
7890

It gets slightly more complex when it comes to 3 dimensional arrays

  • First what comes to mind of majority of people is a cube
            __________	
           /\444444444\
	  /\3\444444444\
	 /\2\3\444444444\
	/\1\2\3\444444444\
	\0\1\2\/33333333\/
	 \0\1\/22222222\/
	  \0\/11111111\/
	   \/00000000\/

(There are many disadvantages to using this form besides awkwardness!)


  • Another way is to display each of the layers as separate 2 dimensional arrays
111
111
111

222
222
222

333
333
333


To Continue (Feel free to add your ideas! :D)



Submitted by Team42