Showing posts with label Open Source. Show all posts
Showing posts with label Open Source. Show all posts

Wednesday, July 23, 2014

Emertxe-OSFY: Articles

Our Team from Emertxe consist of subject matter experts in specific areas (ex: Advanced C programming, Linux Kernel, Software Engineering etc..). This blog was initially created to share our knowledge with broader community, which we are expending further.

Open Source For You (OSFY) is India's top magazine on Open Source, promoted by Electronics For You (EFY) media. For the past couple of months we have been publishing our articles, now we have plans to continue publish articles on various topics. Here are the links to download PDF edition of these articles:



Saturday, May 10, 2014

Pointer Constant & Constant Pointer - Differences

Introduction:
Pointers are always been a complex topic for the newbies into the C programming world. It will be more confusion for the newbies when these 'sharp knives' are used along with some qualifiers like 'const' in C programming. In this blog I want to focus on difference between 'pointer to constant' & 'constant pointer' in order to make the concept very clear.

General Note :
code snippets provided here is tested with GCC compiler [ gcc version 4.8.2 ] running under Linux environment.


Pointer to constant

As the name itself indicates that the value of the variable to which the pointer is pointing is constant in other words a pointer through which one cannot change the value of variable it points is known as a 'pointer to constant'.

Note 1: But these pointers can change the address they 'point to' but cannot change the value at the address they are 'pointing to'.

Declaration

Table-1: showing how to declare 'pointer to constant'



Illustration

Let us consider the code snippet to understand how 'pointer to constant' works,


Fig-1: Illustration example for 'pointer to constant'


In the above example, at line no.12 we are trying to change the value of the variable to which the pointer is 'pointing to', but this is not possible since the value is constant. When the above code is compiled & run, we are getting the output as shown in the below figure.

Fig-2: Output of the code snippet given in Fig-1



Now we will take the same example to show that the 'address' the pointer is containing is not a constant.

Fig-3: Demonstration example to show that the address is not constant.



From the above figure, one can understand that the 'address' where the pointer is containing can be changed but not the value. This can be clearly understood by the pictorial representation given below,



In Brief:

Table-2: Briefing pointer to constant concept




Constant Pointers

A 'constant pointer' is a pointer that cannot change the address it is containing. In other words, we can say that once a constant pointer points to a variable then it cannot point to any other variable. 


Note 2: But these pointers can change the value of the variable they 'point to' but cannot change the address they are 'holding'.

Declaration

Table-3: showing how to declare 'constant pointer'



Illustration

Let us consider the code snippet to understand how 'constant pointer' works,

Fig-7: Illustration example for 'constant pointer'



From the above fig, it is clear that at line no. 14, we tried to change the address of the pointer 'ptr' to some other variable,but according to the concept it is not possible. The output of the above code snippet is given below. Similarly, one can observe at line no. 12, we are trying to change the value of the variable it is 'pointing to' which is possible.

Fig-8: Output of the code snippet given in Fig-7



This can be clearly understood by the pictorial representation given below,


In Brief:
Table-4: Briefing 'constant pointer' concept



Similarly, we can have both pointer to constant & constant pointer in a single statement. This is left as an exercise to analyze.

Application

We can find 'n' number of applications of these concepts in 'C' as well as 'Embedded C' Programming world. One such simple application of 'pointer to constant' is to find the string length of the given string without any attempt to modify the original string as shown in Example 1 and Example 2 gives an idea of usage of 'pointer to constant' in strcmp() function.

Example1:

Fig-12 : Shows the usage of pointer to constant in strlen() library function.


Example2:

Fig-13 : Shows the usage of pointer to constant in strcmp() library function.

Summary

Table-5



Trick: How to understand the differences between pointer to constant & constant pointers.

Note 3: This trick is for all the newbies for the C programming world , who are confusing with constant & pointers.


From the above summary, separate the part before asterisk(*) & part after the asterisk(*) as given in the below table-6.

Table-6


Enjoy C programming :-)

Tuesday, May 6, 2014

void pointers : Its Genericness

 



Void Pointers : Definition

Void pointers are the pointer variables which has no specific data type. These are also called as Generic pointers because it can point to any data type. In General, the compiler has no idea what type of object a void Pointer really points to.

Void Pointers : Declaration

A void pointer is declared like a normal pointer, using the keyword “void” as the pointer’s type as shown below,

Referencing & De-referencing the void pointers

In order to explain, how void pointers can be referenced & De-reference, let we take a small sample code as shown below in Fig 1,

 Fig 1: Referencing & De-referencing of the void pointers

From the above Fig 1, it is clear that while referencing the void * no need to typecast, only when De-referencing the void *, it need to be type-casted otherwise the gcc compiler will give warning along with error note as shown below in Fig 2,
Fig 2: Result obtained while de-referencing the void pointer without typecasting.
  Fig 3: Output after typecasting the void pointer while dereferencing.

Why void pointers are useful ?

One main advantage of using the void pointers is that it can be 're-usable'. Because of this feature of the void pointers 'space' & 'time' complexities can be reduced to some extent which is very critical in Embedded System designing.
They are very useful when you want a same pointer to point to data of different types at different times.
Let us consider a small simple code snippet, to show how void pointers can be re-usable which reduces the space complexity in the example as shown in the Fig 4 given below,
 

Fig 4: Void pointer reusability.

Fig 5: Output of the code shown in Fig 4.

For more clarity let us understand the above code through pictorial representation.
Line No.14 : The vptr is pointing to the address of the integer variable 'i', as shown below in Fig 6.1
Line No.18 : The vptr is pointing to the address of the character variable 'c', as shown below in Fig 6.2
Line No.22 : The vptr is pointing to the address of the float variable 'f', as shown below in Fig 6.3
Line No.26 : The vptr is pointing to the address of the double variable 'd', as shown below in Fig 6.4

Note : xxxx, yyyy, zzzz, aaaa, bbbb are all some arbitrary addresses shown in the above figures from 6.1 to 6.4.
From the figures 6.1 to 6.4 , it is very clear that we have used only one pointer i.e vptr , instead of four different pointers to point to four different variable of different data types, where space complexity is more. Only one thing that the programmer should keep in the mind while coding is that proper typecasting should be done depending on the different data types.
Void pointers are used in places where you need to work with different pointer types in the same code. One commonly used example is the library function qsort:
base is the address of an array, nmemb is the number of elements in the array, size is the size of each element, and compar is a pointer to a function that compares two elements of the array.

Pointer Arithmetic on Void*

Let us learn how to apply pointer arithmetic on the void pointers through the bug code as shown in the Fig 7 given below.
 

Fig 7: Bug code

Fig 8: Output of the bug code shown in Fig 7

From the above result, one can see that we are not getting the expected output. Surprisingly what went wrong ? Let us analyze the above code & output we got.
1. From the output it is very clear that addresses are incremented by one one byte, this is because the gcc compiler assumes sizeof(void) is 1 byte long.
2. So, when we increment void pointer by one, it is incremented by one byte long as one can observe this from the Fig 8(address part).
3. Now coming to the value part, the first value i.e arr[0] is getting printed correct, but after that all the values are wrong, this I am explaining through the pictorial representation as shown in the Fig 9
to Fig 13 below.
Note : The output depends on the endianness of the architecture.
Fig 9
Fig 10
Fig 11
Fig 12
Fig 13
From the above five figures, we can see why we are not getting the expected output. So the corrected code along with expected output is shown in the Fig 14 & 15 given below,

Fig 14 : Correction to the code given in Fig 7

Fig 15: Expected output for the code given in Fig 11.


void pointers can be assigned to any pointer value. One cannot dereference a void pointer without proper typecasting. Functions such as malloc, calloc, free utilize void pointers.

Thursday, April 3, 2014

Pit-falls of Bit-fields




In the past few posts we have been checking various aspects related to bit fields. In this blog, let we focus on how bit-lengths will pose a serious issue to achieve portability in case of bit-fields structures.

Portability is basically about having the same program or application running across various processor architecture. When it comes to embedded systems portability plays a very important role as they have diversified set of hardware. 


To start withlet us take a simple program as given below in Fig 1:




Fig 1: Bit-length pose and portability issue. 
 
After running the above code, output is shown in the given below Fig 2:

Note: source code is tested under gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 version.

 Fig 2: Output of the source code given in Fig 1.

From the above figure 2, it is clear that when we declare the bit-length more than the sizeof(int)[ In our case , it is 4 bytes] , which is compiler dependent we are getting the error at the compile time. The above code perfectly works fine , if the machine WORD size is 64 bits, but fails to work with lower WORD size, which results in portability issue.

Pointers & Bit-fields
I want to focus on one more problem, why pointers cannot be applied for the bit-fields.let me practically explain this problem by taking an example shown in the fig 3 below,

Fig 3: Pointer operation and bit fields

The output of the above source code is given below,


 Fig 4: Output of the source code shown in fig 3.

One can observe from the above fig 4, when tried to reference the bit-field structure variable, compiler is generating an error, this is because direct addressing of the bit-fields structure variables is not possible in C, since the smallest unit of addressable memory in C is a sizeof(char) i.e byte addressable not an bit addressable. This is one of the pit-fall of the bit-field structure in C programming.

From the above two examples, we can conclude that how portability issue is major concern with the bit-fields, and also we saw direct addressing of the bit-fields is not possible in C programming. Apart from this two issues, even sizeof() operator cannot also be applied for the bit-fields since sizeof always returns size in bytes not in terms of bits. Use bit-wise operators instead, they are 100% safe and portable.

Friday, March 28, 2014

Face-off with sizeof()



sizeof : Brief
The unary operator sizeof is used to calculate the size of any datatype, measured in the number of bytes required to represent the type. The result of sizeof is the size of the type of the expression or parenthesized type-specifier that it precedes, and has an unsigned integral type which is usually denoted by size_t ( From Wiki ).
The sizeof() operator behaves differently in comparison with other operators. In this blog let us call out some of the uniqueness of this operator by taking two real time programming examples. The first one is about compile time behavior and second one is during run time behavior.
Case 1: Compile time behavior 
To start with, let us consider the simple code (Fig 1 below):



Fig 1: Sample program to demonstrate the sizeof() operator


Can you guess what would be the output of the above mentioned program? By first look anybody would say it as 4 (Assuming the sizeof(int) is 4 bytes) & 11. But, when I run the program in my system, it is showing 4 & 10 (ref: Fig 2 below)

Fig 2: Output
Why are we getting the value of variable ‘i’ as 10 instead of 11? Here is the reason:
  1. Sizeof operator is the only operator in C, which is evaluated at the compile time. Where sizeof(i++) is replaced the value 4.
  2. One can observe this, shown in the figure given below(inside the box), which contains the assembly code equivalent to the statement in C.



Fig 3: Assembly code generated by the compiler.

Note:
To obtain the assembly code as shown in Fig 3, follow the below given steps.
+ gcc -g filename.c ( In our case sizeof_run.c)
+ objdump -S output_file ( In our case a.out)


From the above figure, one can see that the sizeof() is completely evaluated at the compile time. And the whole sizeof(i++) is replaced by the constant value 4. so, there is no assembly code for i++ at all, which is to be evaluated at the run-time.
Case 2: Run- time behavior
As, I told before Sizeof() operator is the only operator in C, which is evaluated at the compile time.But, there is an exception for this in C99 standards, for variable length arrays.
To start with, Let us consider an code snippet shown below,


Fig 4: Code containing variable length array


Let us see the output, when the above code is compiled & run ( shown in fig 5 below)


Fig 5: Output of the sizeof_run.c


From the above output it is very clear that sizeof() operator is evaluated at the run-time, One can observe the equivalent assembly code generated by the compiler as shown in the Fig 6 given below.
Also, see the difference between the assembly code in the Fig 3 & Fig 6.

Fig 6: Assembly code generated by the compiler, for variable length array.


According to the C99 standards, the sizeof() operator yields the size (in integer bytes) of its operand, which may be an expression or the parenthesized name of a type. If the type of the operand is a variable length array type, the operand is evaluated at run time; otherwise, the operand is not evaluated and the result is an integer constant, during the compile time itself.


In the next blog we will see,
1. Need of sizeof().
2. Cases where sizeof() will not work.
3. How sizeof() is different from function call.

Monday, March 3, 2014

Dangling Pointers : Be "STRICTLY" Avoided !

Pointers are like sharp knives in C-Programming which are having tremendous power. Pointers, when used properly reduces the complexity of the programs to a great extent. But, on the counterpart when not used properly results in adverse effects, in an worst case, it may crash the system.

In this blog, I am mainly focusing on two different situations where Dangling pointers arises and how to avoid it in a simple way.

Note 1:
code snippets provided here is tested with GCC compiler [ gcc version 4.7.3 ] running under Linux environment.

Dangling Pointers : Simply, the pointers not pointing to the valid memory location ( Object ).

To Explain with, I am considering the two different cases , giving rise to Dangling Pointers.

Case :1. When a function returns address of the auto-variables.
Case :2. In dynamic memory allocation, using the block of memory which is already freed.

Case 1: Function returning address of the auto-variables.

Consider the simple code given below in fig 1,

Fig 1: Code returning the address of the local / auto variables.

 

When we run the above program in gcc compiler we get the warning as given in the Fig 2,
Fig 2: Compiler generating warning.



But, What is wrong when address of the auto/local variables are returned ? Let us see this,

1. We know that whenever , there is a function call, new stack frame will be created automatically.

2. When the control returns from the function call, all the memory allocated for that function will be freed automatically.

3. In our example program, we are returning the address of the auto variable and collecting this in the 'int_ptr ' pointer in the main function. So, int_ptr is still pointing to the memory which is freed as per the point no.2 .

4. One can observe allocation & de-allocation of stack frame(Let us called this as fun frame) for the fun() in the Fig 3 given below,
Fig 3: Program Memory & Stack frames.



5. Now, int_ptr becomes 'Dangling'. De-referencing this pointer results in 'Unexpected output'

6. So, always take extra care while playing with pointers & local variables.

Case 2. In dynamic memory allocation, using the block of memory which is already freed.

Consider the below sample code,

Fig 4: Code snippet, showing re-using of block_ptr.



Explanation: For the code snippet shown in Fig 4

Line 5: Memory allocation by malloc().
Line 9: Memory allocated is freed by free() manually.

Note 2: 
In case 1: Memory is freed automatically.
In case 2: Memory is freed manually. This is the one of key difference between stack & heap.

Line 13: Re-using the pointer, which is still pointing to the memory which is already freed. In our example block_ptr is now called as “Dangling Pointer”

But, In case 2 pointer becoming dangling can be avoided by initializing it to 'NULL' immediately after freeing it.
  
block_ptr = NULL;


Dangling pointers are very harmful and results in adverse effects in the embedded systems programming.So. It should be “STRICTLY” avoided.