[Bug 2012076] Re: printf function outputs different results for same arguments
Simon Chopin
2012076 at bugs.launchpad.net
Fri Mar 17 16:23:58 UTC 2023
Hi,
You're invoking undefined behaviour in your examples by providing non-
double arguments for a %f conversion specifier. In particular, when you
give a pointer rather than a double, GCC completely discards the
argument, as illustrated in this example (see eax set to 0 in first
printf call, 1 to the other ones):
https://godbolt.org/z/1EcxK9T53
If you cast the argument appropriately, it prints the correct value.
The relevant section in the C17 specification is 7.21.6.1, particularly
paragraph 9:
> If a conversion specification is invalid, the behavior is undefined.286) If any argument is not the
correct type for the corresponding conversion specification, the behavior is undefined.
Closing this as Invalid.
** Changed in: glibc (Ubuntu)
Status: New => Invalid
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to glibc in Ubuntu.
https://bugs.launchpad.net/bugs/2012076
Title:
printf function outputs different results for same arguments
Status in glibc package in Ubuntu:
Invalid
Bug description:
A union is defined for storing different datatype values; and all
values' data lengths are the same.
Since the data lengths of the union members are the same, i suppose
that printf function can have specified output format with specifying
any union member.
The scenario can be seen in the following sample code. Variable v is
assigned with a floating number in the beginning; to output this
value, the output format is specified as "%f" in the printf function
format string, but the value is given by v.p, which is a void * type,
as next argument. See the output results of the printf("v.p_f = %f\n",
v.p); statement, there are 3 different result.
//===========================
#include <stdio.h>
#include <stdlib.h>
typedef union
{
double f;
long int i;
void *p;
} type_t;
void func2(int a, int b, type_t v);
int main(void)
{
type_t v;
unsigned char *p;
printf("sizeof(double) = %ld\n", sizeof(double));
printf("sizeof(long int) = %ld\n", sizeof(long int));
printf("sizeof(void *) = %ld\n", sizeof(void *));
printf("sizeof(type_t) = %ld\n", sizeof(type_t));
v.f = 123.456789;
printf("\nIn %s()\n", __FUNCTION__);
printf("v.p_f = %f\n", v.p);
printf("v.i_x = %lX\n", v.i);
printf("cont. = ");
p = (unsigned char *) &v;
for (int i = 7; i >= 0; --i)
printf("%02X", p[i]);
printf("\n");
printf("v.p_p = %p\n", v.p);
printf("v.i_d = %ld\n", v.i);
printf("v.f_f = %f\n", v.f);
printf("v.p_f = %f\n", v.p);
func2(1, 2, v);
printf("\nIn %s()\n", __FUNCTION__);
printf("v.i_d = %ld\n", v.i);
printf("v.p_f = %f\n", v.p);
printf("v.f_f = %f\n", v.f);
printf("v.p_f = %f\n", v.p);
printf("\n");
#ifdef __GNUC__
printf("__GNUC__\n");
printf("__VERSION__ = %s\n", __VERSION__);
#endif
fflush(stdout);
#ifdef __linux__
system("`find /usr/lib -executable -name *libc.so*` --version");
printf("\n");
#endif
return (0);
}
void func2(int a, int b, type_t v)
{
unsigned char *p;
printf("\nIn %s()\n", __FUNCTION__);
printf("v.p_f = %f\n", v.p);
printf("v.i_x = %lX\n", v.i);
printf("cont. = ");
p = (unsigned char *) &v;
for (int i = 7; i >= 0; --i)
printf("%02X", p[i]);
printf("\n");
printf("v.p_p = %p\n", v.p);
printf("v.i_d = %ld\n", v.i);
printf("v.f_f = %f\n", v.f);
printf("v.p_f = %f\n", v.p);
}
//==================================
sizeof(double) = 8
sizeof(long int) = 8
sizeof(void *) = 8
sizeof(type_t) = 8
In main()
v.p_f = 0.000000
v.i_x = 405EDD3C07EE0B0B
cont. = 405EDD3C07EE0B0B
v.p_p = 0x405edd3c07ee0b0b
v.i_d = 4638387916139006731
v.f_f = 123.456789
v.p_f = 123.456789
In func2()
v.p_f = 0.000000
v.i_x = 405EDD3C07EE0B0B
cont. = 405EDD3C07EE0B0B
v.p_p = 0x405edd3c07ee0b0b
v.i_d = 4638387916139006731
v.f_f = 123.456789
v.p_f = 123.456789
In main()
v.i_d = 4638387916139006731
v.p_f = -5486124068793688683255936251187209270074392635932332070112001988456197381759672947165175699536362793613284725337872111744958183862744647903224103718245670299614498700710006264535590197791934024641512541262359795191593953928908168990292758500391456212260452596575509589842140073806143686060649302051520512.000000
v.f_f = 123.456789
v.p_f = 123.456789
__GNUC__
__VERSION__ = 9.4.0
GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.
Copyright (C) 2020 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.
Compiled by GNU CC version 9.4.0.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/2012076/+subscriptions
More information about the foundations-bugs
mailing list