koktelici
koktelici

Reputation: 41

Pointers in C. Need explanation for this tiny code

#include <stdio.h>

int* func()
{
    static int a = 5; /* line 5 */
    printf("%d\n",++a);
    return &a; /* line 7 */
}

int main(void)
{
    int *b = func(); /* line 12 */
    (*b)++;
    func();
}

This is a code example of test for coding job so it is not necessary optimal. I have basic knowledge of c++ and Java but these are pointers in C which I have trouble with.

  1. func()'s return type is pointer but it returns the adress of the integer (line7). Does the fact that integer is static(line 5) have to do anything with this?

  2. What does line 12 actually do?

Output of this code is:

6

8

Upvotes: 3

Views: 150

Answers (6)

Zaynul Abadin Tuhin
Zaynul Abadin Tuhin

Reputation: 32031

i think there is issue with static variable with initialization because Initialized are the ones that are given value from code at compile time. These are usually stored in DS though this is compiler specific.

The other type is uninitialized statics which are initialized at run time and are stored into BSS segment though again this is compiler specific

 #include <stdio.h>

int* func()
 {
   static int a;
   a = 5;
   printf("%d\n",++a);
   return &a;
 }

int main(void)
{
  int *b = func();
  (*b)++;
  func();
 }

this code output is

6

6

but the difference is only with initialization

Upvotes: 0

Useless
Useless

Reputation: 67872

I have basic knowledge of c++

No, you really don't. I'm going to explain everything, but you should understand that this isn't some weird C-style thing, it's basic C, and also (although they're different languages), basic C++. If you don't understand pointers, you know at most a simplified, Java-style subset of C++.

  1. func()'s return type is pointer but it returns the adress of the integer (line7). Does the fact that integer is static(line 5) have to do anything with this?

    I'm not entirely sure what your question is here.

    The integer a is static, that's true, and it's relevant to why the function works. But, it isn't relevant to the syntax of taking an address.

    Your function is effectively identical to this:

    /* static */ int global_a = 5;
    int* func2()
    {
        printf("%d\n",++global_a);
        return &global_a;
    }
    

    except that global_a would be visible to other code in the same translation unit, and the original static a is only visible inside the function. Otherwise they have the same lifetime and behaviour.

    Note that I commented out the static qualifier for global_a - it's still legal, but means something slightly different at global rather than function scope.

    ... return type is pointer but it returns the address of the integer ...

    that's fine, and nothing to do with the lifetime of a. The address of an integer (&a) is a pointer int *. That's what the expression means. This is always true for all variables and the static keyword doesn't change anything.

    What the static keyword does affect is the lifetime of a - as mentioned above, it gives it the same lifetime as a global, while keeping its name restricted to inside the function. Compare this other version:

    int* func()
    {
        /*static*/ int a = 5;
        printf("%d\n",++a);
        return &a;
    }
    

    This is totally broken.

    • Firstly, it will always print 6, as each time you call the function it creates a new local variable called a, sets it to 5, and then increments it. The static a is instead initialized to 5 once, and that same a incremented each time the function is called.

    • Secondly, returning the address of a local variable is problematic, because a will have ceased to exist by the time the caller receives the pointer. You can't ever do anything with the pointer returned, unless a is static, or global, or otherwise lives longer than the function call.

  2. What does line 12 actually do?

    int *b declares a variable, called b, of type pointer to integer

    = func() calls the function func() we've just discussed

    int *b = func(); calls function func, and assigns the result (the pointer, which is the address of a) to variable b.

    So, b is now a pointer to an integer. The integer in question is a, which exists outside the scope of func because it's static, even though we couldn't refer to it by name outside that scope.

    The expression *b dereferences the pointer, which is an unfortunate name in this context, because it actually yields a reference of type int&, still to a.

Upvotes: 2

haccks
haccks

Reputation: 106142

Does the fact that integer is static(line 5) have to do anything with this?

Yes. Otherwise returning a pointer to an automatic local variable will invoke undefined behavior.

The lifetime of a static local variable ends when the program terminates. So, its memory location is allocated till the end of the program and therefore its location can be returned.

The line (*b)++; dereference the value pointed by b and then increments the value by 1.

Upvotes: 5

Serge Ballesta
Serge Ballesta

Reputation: 149185

A pointer is not that different from a Java or C++ reference, and C++ does allow the use of pointers.

Here is what happens:

func contains a static variable a. A static variables has a lifetime that extends throughout the whole program and in C is initialized before the main is called (may be at compile or startup time). Here func increases and print the value of its static variable and returns its address.

main initially calls func and stores the address of the static variable in a pointer b. b is used to increase the value of the static variable, and func is called once again.

Upvotes: 2

VinayKumar.M
VinayKumar.M

Reputation: 147

1) It is not a good idea to return the address of a local variable outside the function, so you would have to define the local variable as static variable.....So line 5 has nothing to do with this ..........It Should be only return a and not return &a.

return a;

Upvotes: -3

Christophe
Christophe

Reputation: 73637

Func() has a local "static" variable a, which means that a is shared between all its invocations of the function.

The function returns a pointer to this variable. Via this pointer, the world outside func() can acces to this local static.

So in line 12, in main(), a pointer is created and initialised to point to a. Whenever you deregerence b, you then directly acces the content of a (including modifications)

Upvotes: 1

Related Questions