Gcc 9.4 strangeness

I don't know where else to post this question, so I hope there are C programmers here.

I have a line of code that I have isolated into a 1-line C program that behaves strangely. If I have this code:

int main() {
    printf("%d %d %d\n", 1, 2, 3);
    return 0;
}

Pretty sure you can guess the output will be 1 2 3. Not that Earth-shattering.

But let's suppose I deliberately change the first number a float.

int main() {
    printf("%d %d %d\n", 3.14, 2, 1);
    return 0;
}

The output seems to depend on the compiler, as far as I've played with this. In any event, there are the usual warnings you would expect; but the output is shuffled around with the 3.14 replaced by a wholly different number (usually a large integer).

I am not too concerned about the type-clash error here, but I am more concerned about the shuffling of numbers. On my Ubuntu 24.4 system,
I get:
2 1 1015677328

Can anyone tell me why the order of the numbers have changed? That is really what I am most interested in.

Paul

Welcome Paul!

If the wrong data types are fetched from the stack then bad things can happen...
Of course you should do

    printf("%d %d %d\n", round(3.14), 2, 1);

or

    printf("%.f %d %d\n", 3.14, 2, 1);

Hi @paulk,

you may have a look at the last post here: c - Why does printf implicit float to int conversion not work? - Stack Overflow

@paulk, there's no strangeness here, the compiler reveals all...ignore at your peril

gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

gcc -o p2 p2.c
p2.c: In function ‘main’:
p2.c:2:23: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
    2 | int main() { printf("%d %d %d\n", 3.14, 2, 1); return 0; }
      |                      ~^           ~~~~
      |                       |           |
      |                       int         double
      |                      %f

@paulk , this'll fry your head ...

cat p5.c
#include <stdio.h> 
int main() { printf("%d %f %d\n", 2, 1, 3.94); return 0; }

gcc -o p5 p5.c 
p5.c: In function ‘main’:
p5.c:2:26: warning: format ‘%f’ expects argument of type ‘double’, but argument 3 has type ‘int’ [-Wformat=]
    2 | int main() { printf("%d %f %d\n", 2, 1, 3.94); return 0; }
      |                         ~^           ~
      |                          |           |
      |                          double      int
      |                         %d
p5.c:2:29: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘double’ [-Wformat=]
    2 | int main() { printf("%d %f %d\n", 2, 1, 3.94); return 0; }
      |                            ~^           ~~~~
      |                             |           |
      |                             int         double
      |                            %f

$ ./p5
2 3.940000 1

have fun :nerd_face:

I skimmed through the article, and, so I invoked "undefined behaviour". Ah, that might explain why I got a big number for 3.14 - printf doesn't do rounding, and so it just went momentarily insane for a microsecond and gave a really big integer instead. :slight_smile:

So, I would suppose that included in "undefined behaviour" is changing the order of the parameters. Or is there a logical reason that the misbehaved parameter got moved to the back and the other two shifted up.

Oh, I saw that error as well. The type clash was deliberate. I was trying to see if it would compile, or (like Java) throw some kind of exception, but instead, it gave me the numbers with some out of order, and one weird one where the float would have been if I used %f.

I understand the warning, and that %d is something I shouldn't do if I needed %f or to use round(3.14) instead.

I just thought the shuffling of numbers was strange and unnecessary, and had no problem with getting numbers like -2014752368 for using a bad format specifier.

You know, I would have no problem if it just refused to compile and left it up to me to fix that. It's like it's trying to fix the code for you.

@paulk , below will result in no output due to compilation issues

gcc -Wall -Wextra -Werror -o p5 p5.c

rtfm will help you as well :nerd_face: