Search This Blog

Tuesday, October 5, 2010

typecasting-several situations!!

Typecasting,when dealt alone,is not a difficult concept to understand and imbibe.However,confusions surface when we encounter a code in which a few different concepts of C are mixed up.Also our attempts, to arrive at intended results,go awry when we use typecasting in various situations without a clear understanding or due to intangible mistakes.I am describing a few here which i have frequently encountered.

consider the following piece of code and try to comprehend the output they produce...


#include
main(){
int a[]={10,20,30,40,308};
char *p=(int*)a;
printf("output:%d\n",*p);



/*output:10
*pointer is of char type hence at most it can de-reference 1 byte of the *integer type element of the array.10 is at the base address and can be *represented well in 8 bits as 0000 1020 (as a four byte integer it would be FFFA *or 0000 0000 0000 0000 0000 0000 0000 1020).Now on a little endian machine, the *pointer reads from *lower address.Hence here in this case character pointer 'p' *can read and accommodate well the value 10.
*/


printf("output:%d\n",*(p+1));


/*output:0
*What happens here is a bit hazy at the first look.Lets analyze the operations on *the pointer and see where they take us.Pointer p is of char type hence when we *add 1 to it,it would move to the next one byte chunk in the memory.It was pointing *at the first byte of the base address in beginning so here it moves to the next *byte(not to the next element in the array,which is conclusion at first sight),that *happens to be 0000 0000(refer to the bit representation of first element in *previous explanation).Hence the output 0.
*/


printf("output:%d\n",*(p+4));


/*output:20
*this justifies the above explanation.When we move the char pointer by 4 bytes we
*are moving to the first or lower byte of second element of an int array.As int
*occupies 4 byte.
*/


printf("output:%d\t%d\n",*p,*(++p));


/*This has to do with the working of printf function. Output would be undefined *here since two operations are carried out on same operand P in argument list of *printf function.Hence it may not print value at the lower and next higher byte
*of the base address.
*/



p = (int*)p + 4;
printf("output:%d\n",*(int*)p);


/*output=308
*P a a little attention here.We have typcasted p to an int pointer and added 4 to *it on the right hand side of the expression and assigned this value to the p,which *is a char pointer(remember its declared so,typecasting it to integer does not *change its fundamental behavior).However again in printf we have typecasted it to *int pointer.Hence it prints value represented by four bytes at the 4th index(i.e. 5th element)which is 308(308:0000 0000 0000 0000 0000 0001 0011 0100).Had it not been typecasted in pritnf again result would have been as below.
*/


printf("output:%d\n",*p);


/*output:52
*After the operations in the previous step.pointer is pointing to the lower byte of *fifth element but since it is char pointer by nature,it can read only one byte *from where it is pointing.And that is equivalent to 52(refer the binary *representation of 308 above)
*/


}

Even though it does not cover all that could be done with typecasting,this article provides an insight to look at cases little deeper.After all C is the language where you don't learn new things until you screw it up somewhere!

Friday, October 1, 2010

An interesting case of typedef!

Consider the following piece of code

typedef char *char_ptr;
const char_ptr p
;


Now the simple question after this piece of code is-what is constant here,the pointer char_ptr or variable p which is of type
char_ptr??

At first sight we jump at conclusion that char_ptr is constant,however the case is little different.

typedef substitutions are not purely textual like that of define.
Consider
const int i;
Here,as you can easily conclude i is constant.And same logic applies to the piece of code in discussion.

const can affect a pointer variable in two (or more) different ways: either the pointer can be qualified, or the value pointed to.

int * const p;

the pointer p is qualified, but when you write

const int * p;//or int const *p;

the value pointed to is qualified.

Contrasting with

define

Now, if you say

#define x int*

and then

const x p;

the result is exactly as if wrote

const int* p;

(due to exact textual replacement in pre-processing)

When you write

typedef int * x;

x is seen as a new type by compiler and interpreted as a pointer to int.
Hence in

const x y;

the variable y is qualified, similar to

const int y;

About this blog.....

The main purpose of this blog is to throw some light in the dark and confusing alleys and corners of C. C is one of the most powerful programming languages. You think of anything running on computer and C is there,either running underneath or openly on top.Its versatility has made it most dependable language for system programming,writing OS, compilers,embedded systems,other higher level programming languages and whatnot. It has a limited grammar and programming constructs,when compared with other languages,nonetheless it does not undermine its capability to tackle any case which other languages can handle.For a beginner or intermediate level programmer,it becomes a hard nut to crack when C throws its esoteric features as errors and segmentation fault.When I started learning C,I am still a learner,I could not find a single book or resource which could address all the questions and doubts.This is my attempt to collect the explanations of some frequently encountered questions and doubts.

PS- This blog is hard-coded to evolve with my progress in C.