-1

I created the following code while playing with pointers -

#include <stdio.h>
int main()
{
    float a=1000;
    int *c=&a;
    float *d=&a;
    printf("\nValue of a is %f",a);
    printf("\nValue of a is %f",*c);
    printf("\nValue of a is %f",*d);
    printf("\nValue of a is %f",*&*c);
    printf("\nValue of a is %f\n",*&*d);

    int b=2000;
    int *e=&b;
    float *f=&b;
    printf("\nValue of b is %d",b);
    printf("\nValue of b is %d",*e);
             printf("\nValue of b is %d",*f);      //Will produce 0 output
             printf("\nValue of b is %d",*&*e);
             printf("\nValue of b is %d\n",*&*f);  //Will produce 0 output

             float g=3000;
             float *h=&g;
             printf("\nValue of g is %f\n",*h);
}

Which has produced the output -

aalpanigrahi@aalpanigrahi-HP-Pavilion-g4-Notebook-PC:~/Desktop/C/Daily programs/pointers$ ./pointer004

Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000
Value of a is 1000.000000

Value of b is 2000
Value of b is 2000
Value of b is 0
Value of b is 2000
Value of b is 0

Value of g is 3000.000000

And For the second part where the variable b has been declared as integer and *e and *f are pointers , the value of b is printing out to be 0 in case of *f and *&*f (as shown in the code) but this has worked in the case above that where variable a has been declared as a floating point number.

Why is this happening ??

  • 1
    It is not sensical to covert between types using pointer, but try printing sizeof(int). If the answer is 8 then your issue is that the first four bytes of memory are zero which is where your float is pointing to. In any case don’t expect 2000 as ieee is a different representation – Philip Brack Oct 16 '17 at 15:22
  • 4
    The undefined behavior is rampant here. First, trying to access an `int` value by via a `float *` violates [strict aliasing](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and is undefined behavior. Second, given `float *f` for a variable, trying to print its value with `printf("\nValue of b is %d",*f);` is also undefined behavior since `*f` refers to a `float`, but you're trying to print it with a `%d` format string. That's also undefined behavior. – Andrew Henle Oct 16 '17 at 15:26
  • @PhilipBrack More likely, `int` is four bytes. Because `float` (assumed to be 4 bytes here) values are promoted to `double` (assumed to be 8 bytes) as a result of [default argument promotion for vararg functions.](https://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls) – Andrew Henle Oct 16 '17 at 15:28
  • @PhilipBrack But if this is the case then why is the output produced in the first condition. – Aashish Loknath Panigrahi Oct 16 '17 at 15:29
  • 1
    Undefined behavior is undefined. – melpomene Oct 16 '17 at 15:40
  • `int *c=&a;` is UB so rest of code is moot. Avoid pointer aliasing - use a `union` – chux - Reinstate Monica Oct 16 '17 at 15:59

2 Answers2

1

This issue is system depended. In some platforms you will receive 0 and in some -1. That is because you are printing the float as a int using the %d. The float in most platform is 4 bytes (check it using sizeof(float)). The binary value of the float number 2000 is 01000100111110100000000000000000 and it mark as a float so when you are trying to print it with %d it encounters undefined behavior.

Eliad Cohen
  • 378
  • 2
  • 10
-1

Why is this happening ??

-shrugs- strange things happen when you try to fly planes backwards, with blindfolds and earplugs in. Thus, you should always learn to fly a plane by reading as much as possible before you jump into the cockpit.

Take off your blindfold and earplugs. Open your eyes, and get to reading a book. If you're already reading a book, get a new one, because this one's not working for you.


printf("\nValue of a is %f",*c); is undefined behaviour, because an attempt is made to print an expression which has type int (*c) using a format specifier which claims it's a double. C11/7.21.6.1p9 states this blatantly:

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

Note that I didn't imply any consequences, positive or negative. It's undefined behaviour, meaning we can't tell whether it'll "work" (whatever that means) or whether it'll "crash".


Thus is the nature of UB. You probably didn't notice this error, because it "works", but it's not required to... moving on, we come to the example you ask about:

printf("\nValue of b is %d",*f);

A similar situation applies here; *f is a float expression, and %d tells scanf to expect an int value. The behaviour is undefined, which happens to mean in this case, you see a confusing "0".

You can not define the undefined by claiming it shouldn't print 0. It's allowed to print 0, because you've allowed it to by causing undefined behaviour. Similarly, if you were to see a crash, it's allowed to crash because you've allowed it to crash by causing undefined behaviour.

Also of relevance is C11/6.5p7:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:88)

  • a type compatible with the effective type of the object, a qualified version of a type compatible with the effective type of the object,
  • a type that is the signed or unsigned type corresponding to the effective type of the object,
  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or a character type.

Hence, more often than not, if you're casting something you're likely making a mistake... a common mistake, involving not reading a book, for example... so... which book are you reading?

Community
  • 1
  • 1
autistic
  • 1
  • 3
  • 35
  • 80
  • Well I am using a book for beginners called as "Let Us C". Can you assist me , by telling me what book should I choose as a beginner which can clear up my fundamentals. – Aashish Loknath Panigrahi Oct 17 '17 at 04:36
  • At this point in time, I've not come across any C-related resource which is both "beginner-friendly" and "accurate", though that's no fault of the resources as C itself is not particularly "beginner-friendly" or "accurate". Let Us C, among other resources written by Kanetkar, is on the blacklist as far as accuracy goes. I guess we might have differences on what a "beginner" is. Before learning C from a reputable resource, you should first have developed some fundamental understanding of procedural programming, perhaps even programming in general. I feel confident that you have that fundamental – autistic Oct 18 '17 at 04:02
  • ... understanding, so I wouldn't really consider you a "beginner", as you seem to have understood that much... and I can recommend K&R2E. Do the exercises as you stumble across them. Don't move past the exercises until you've completed them to such a degree that you're sure you've answered to a university level of proficiency. – autistic Oct 18 '17 at 04:06