-2
#include <stdio.h>
#include <math.h>

int main(void)
{
    float a = 16777215;
    int b = pow(2, 26);
    float c = 22345678;
    printf("%f\n", a);
    printf("%f\n", b);
    puts("---------------");
    printf("%f\n", c);
    printf("%f\n", b);
    return 0;
}

output:

16777215.000000
16777215.000000
---------------
22345678.000000
22345678.000000

why the former printf output can have influence to the subsequent printf output?

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 2
    Enable warnings, `int` isn't `%f`. This is undefined behaviour. – tadman Feb 23 '21 at 07:32
  • You are invoking *undefined behavior* by passing data having wrong type. Determining detailed reason for this specific result will require some knowledge about the environment including calling convension. – MikeCAT Feb 23 '21 at 07:34

3 Answers3

0

You need to match the type or strange things can happen:

printf("%d\n", b);

Compiling the original code with clang gives helpful warnings:

pow.c:10:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
    printf("%f\n", b);
            ~~     ^
            %d
pow.c:13:20: warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
    printf("%f\n", b);
            ~~     ^
            %d

varargs functions like printf have a hard time pinning down their type requirements, it's up to compilers like clang to go the extra mile and show hints like this. You'll need to be extra careful when calling functions of that sort and be sure you're doing it precisely as documented.

As to how this ended up happening, it's not clear, but it doesn't have to be. Undefined behaviour is just that: Anything can happen. It could print the same thing. It could work. It could crash. There doesn't have to be an explanation.

tadman
  • 208,517
  • 23
  • 234
  • 262
0

b isn't a float. Try %i for integer or %d for decimal.

 #include <stdio.h>
 #include <math.h>
 
 int main(void)
 {
     float a = 16777215;
     int b = pow(2, 26);
     float c = 22345678;
     printf("%f\n", a);
     printf("%i\n", b);
     puts("---------------");
     printf("%f\n", c);
     printf("%i\n", b);
     return 0;
 }
Ruben
  • 194
  • 2
  • 11
0

Undefined behavior as you try to print integer with %f

Try

printf("%d\n", b);

To answer your specific question, my guess is that, at the assembly level, if the conversion is not correctly indicated, it will jump to ret, using the value previously stored in eax register.

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81