Pages

Monday, April 23, 2012

size zero ..

*Type - Finding and observation

sizeof operator, is a common way to know about the types in C/C++. Ever thought of seeing something which is making sizeof return 0. Yes, I  just discovered a type which returns 0 for its variables.

What did this code give in your machine ..
char ch[0];
printf("%d",sizeof(ch));

doesnt matter much though ;)

It printed 0 in mine-  gcc/ Ubuntu 11.04/ 32 bit machine ..

Tuesday, November 29, 2011

"..never believe that "const" is some guarantee that the memory under the pointer doesn't change.." - linus torvaldus

I think a lot of this is bogging down in a couple of different areas;
people are arguing past each other over:

 - What does const mean?
 - What could const mean?
 - What should const mean?

Many people will produce different answers for these three.

In fact, the answer to the first, in terms of the Standard, is
`almost nothing at all'.  For instance:

 const int c = 3;
 ...
 printf("%d\n", c);

could print 42, if c somehow changes despite its being declared
const.  No strictly conforming program can change `c' directly,
but the object is usually subject to change through external factors
(e.g., direct writes on systems that lack memory protection, or
memory corruption from alpha particles, or whatnot).  All the
Standard gets you is these two things:

 - An object that is defined with `const' may not be modified
   in any way by a strictly conforming program (so since `c'
   above is const, it may not be modified; if it *is* modified,
   the behavior is undefined).

 - An lvalue with the `const'-qualifier may not be assigned-to.
   This mainly buys you some compile-time typo/braino checking,
   e.g., a diagnostic if you write `c = 7' instead of `v = 7'
   (note that c and v are next to each other on many keyboards).

The answer to the second (`what could const mean') is quite open
ended: there are plenty of possible meanings.

The answer to the third, `what should const mean', depends on the
person asked.

Note also that the following strictly conformant program *must* print
"3, 7":

 #include 

 int v;
 int *p;

 void f(const int *);

 int main(void) {
  p = &v;
  f(&v);
  return 0;
 }

 void f(const int *vp) {
  int i, j;
  i = *vp;
  *p = 7;
  j = *vp;
  printf("%d, %d\n", i, j);
 }

The compiler *cannot* assume that i and j are equal, despite the
fact that *vp is const-qualified, because vp can (and does) point
to a modifiable lvalue and the assignment to *p can (and does)
modify the lvalue to which the const-qualified `vp' pointer points.
As this example illustrates, `const' does *not* mean `constant'.

reference : http://yarchive.net/comp/const.html [is place where i copied], it also contains the similar and more advance discussions including mail written by torvaldus throwing some insights..

Tuesday, October 25, 2011

Demystifying complex C declarations.

I have seen many times people complaining of interviewer giving them shit looking declaration and ask us to tell them what it is..
Ex. :
int * p :
pointer to an integer :
[:D]..
okay.. how about this..

 void (*signal(int, void (*fp)(int)))(int); 


To some even this may look easy but to me I put down my pencil and got back to facebook to relieve from tension.
Following is the illustration of one simple method I stumbled across and felt it worked for any kind of declaration.

If there is/are any exception(s) to the following, please feel free to discuss.


[This was posted to comp.lang.c by its author, David Anderson, on 1994-05-06.].. and I read on c-facts ;)

The ``Clockwise/Spiral Rule''

By David Anderson

There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration! There are three simple steps to follow:
  1. Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:
    [X] or []
    => Array X size of... or Array undefined size of...
    (type1, type2)
    => function passing type1 and type2 returning...
    *
    => pointer(s) to...
  2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.
  3. Always resolve anything in parenthesis first!

Example #1: Simple declaration

                     +-------+
                     | +-+   |
                     | ^ |   |
                char *str[10];
                 ^   ^   |   |
                 |   +---+   |
                 +-----------+
Question we ask ourselves: What is str?
``str is an...
  • We move in a spiral clockwise direction starting with `str' and the first character we see is a `[' so, that means we have an array, so...
    ``str is an array 10 of...
  • Continue in a spiral clockwise direction, and the next thing we encounter is the `*' so, that means we have pointers, so...
    ``str is an array 10 of pointers to...
  • Continue in a spiral direction and we see the end of the line (the `;'), so keep going and we get to the type `char', so...
    ``str is an array 10 of pointers to char''
  • We have now ``visited'' every token; therefore we are done!

Example #2: Pointer to Function declaration

                     +--------------------+
                     | +---+              |
                     | |+-+|              |
                     | |^ ||              |
                char *(*fp)( int, float *);
                 ^   ^ ^  ||              |
                 |   | +--+|              |
                 |   +-----+              |
                 +------------------------+
Question we ask ourselves: What is fp?
``fp is a...
  • Moving in a spiral clockwise direction, the first thing we see is a `)'; therefore, fp is inside parenthesis, so we continue the spiral inside the parenthesis and the next character seen is the `*', so...
    ``fp is a pointer to...
  • We are now out of the parenthesis and continuing in a spiral clockwise direction, we see the `('; therefore, we have a function, so...
    ``fp is a pointer to a function passing an int and a pointer to float returning...
  • Continuing in a spiral fashion, we then see the `*' character, so...
    ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to...
  • Continuing in a spiral fashion we see the `;', but we haven't visited all tokens, so we continue and finally get to the type `char', so...
    ``fp is a pointer to a function passing an int and a pointer to float returning a pointer to a char''

Example #3: The ``Ultimate''

                      +-----------------------------+
                      |                  +---+      |
                      |  +---+           |+-+|      |
                      |  ^   |           |^ ||      |
                void (*signal(int, void (*fp)(int)))(int);
                 ^    ^      |      ^    ^  ||      |
                 |    +------+      |    +--+|      |
                 |                  +--------+      |
                 +----------------------------------+
Question we ask ourselves: What is `signal'? Notice that signal is inside parenthesis, so we must resolve this first!
  • Moving in a clockwise direction we see `(' so we have...
    ``signal is a function passing an int and a...
  • Hmmm, we can use this same rule on `fp', so... What is fp? fp is also inside parenthesis so continuing we see an `*', so...
    fp is a pointer to...
  • Continue in a spiral clockwise direction and we get to `(', so...
    ``fp is a pointer to a function passing int returning...''
  • Now we continue out of the function parenthesis and we see void, so...
    ``fp is a pointer to a function passing int returning nothing (void)''
  • We have finished with fp so let's catch up with `signal', we now have...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning...
  • We are still inside parenthesis so the next character seen is a `*', so...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to...
  • We have now resolved the items within parenthesis, so continuing clockwise, we then see another `(', so...
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning...
  • Finally we continue and the only thing left is the word `void', so the final complete definition for signal is:
    ``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning nothing (void)''
The same rule is applied for const and volatile. For Example:
 const char *chptr;
  • Now, what is chptr??
    ``chptr is a pointer to a char constant''
How about this one:
 char * const chptr;
  • Now, what is chptr??
    ``chptr is a constant pointer to char''
Finally:
 volatile char * const chptr;
  • Now, what is chptr??
    ``chptr is a constant pointer to a char volatile.''
Practice this rule with the examples found in K&R II on page 122.
Copyright © 1993,1994 David AndersonThis article may be freely distributed as long as the author's name and this notice are retained.


Friday, October 21, 2011

Open Question : Reason for restriction in conversion of pointers to reference of pointer to const

OS : Win XP
Env: VC++ 2008


void foo_ptr(const char * & ptr) //reference to a pointer to a constant character
{
return;
}


//allowed
void foo_char(const char & p_Char) //reference to a constant character
{
return;
}
int main()
{
char ch = 'd';
char *ptr =  "anuh";

foo_char(ch);


! //foo_ptr(ptr); //NOT ALLOWED syntax error, vc++, 2008
return 0;
}

I am interested in knowing the reason of syntax error when we call foo_ptr. When foo_char is allowed why not foo_ptr.

just to keep updated the same question has been asked http://stackoverflow.com/questions/7850843/c-need-reason-for-error-cannot-convert-parameter-1-from-char-to-const


Thursday, October 6, 2011

Why size(Structure) differ from sum of actual sizes of individual members

Same Data Members : Different Sizes

struct  MyStructA {
   char a;
   char b;
   int  c;
};

struct MyStructB {
   char a;
   int c;
   char b;
};

int main(void) {
        int sizeA = sizeof(struct MyStructA);
        int sizeB = sizeof(struct MyStructB);

        printf("A = %d\n", sizeA);//->8
        printf("B = %d\n", sizeB);//->12 in arch x86, DevCPP Compiler
        getch();
        return 0;
}
(via : forum)


(from Wiki)

struct student{
  char grade; /* char is 1 byte long */
  int age; /* int is 4 bytes long */
};
 
printf("%zu", sizeof (struct student));
The reason for this is that most compilers, by default, align complex data-structures to a word alignment boundary. In addition, the individual members are also aligned to their respective alignment boundaries. By this logic, the structure student gets aligned on a word boundary and the variable age within the structure is aligned with the next word address. This is accomplished by way of the compiler inserting "padding" space between two members or to the end of the structure to satisfy alignment requirements. This padding is inserted to align age with a word boundary. (Most processors can fetch an aligned word faster than they can fetch a word value that straddles multiple words in memory, and some don't support the operation at all[3]).

This also has roots into the bus size, (which is word size), making the size of structure integral multiple of bus size helps processor fetching the data faster.
How ?? : > i  l update as soon as i get crude answer.

Wednesday, October 5, 2011

C/C++ : free or delete will NOT release memory back to OS

following is what i found really useful for knowledge sake and would also help in case we are planning to build large systems using C/C++. I have read about this on post by Murali MALLINA, Sr. Soft E in Alcatel Lucent on one of the internal forums.

he said as 

When you call free() or delete(), it will NOT really release any memory back to OS. Instead, that memory is kept with the same process until it is terminated. However, this memory can be reused for any future allocations by the same process. This freed memory is never released to OS, even when the system is out of memory and other processes need memory. That means, a process is stuck with the largest level of memory allocation throughout its life time.

This is big concern for most processes that are expected to run (literally) forever without a restart.

There is an alternative, by linking to mapmalloc library, that uses map/unmap instead of sbrk for memory allocation. When linked with this library, memory could be really released to operating system when free/delete is called. However, memory allocation could be potentially 5 times slower. One heck of a trade off!


Hope this information will help in your designs.  

:-o :-o

Friday, September 30, 2011

trees and data structure : skipping double pointer

many times it is felt to pass head pointers as parameter to functions...

v  simple solution is to pass by reference..
this way u dnt have to change internal syntaxes in side your insert functions and all other functions where modification in the data structure is required.


void insert ( struct T * & node, int data)
{
if (!node)
{ node = (struct T * )malloc(sizeof(struct T));
node->data = data;
node->left = node->right = NULL;
}
}