Discussion:
printf error...
g***@sdf.org
2012-01-17 16:56:17 UTC
Permalink
Hi list,

I try to compile a very simple program with pcc (on Debian, AMD64, latest
CVS sources):

int main () { printf ("%.10f", 10.0); return 0; }

$ pcc foo.c
$ ./a.out
Segmentation fault
$ gdb a.out
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: a.out

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main ()

Is there a way to make this work? I tried various alternatives (sprintf,
fprintf, etc.), but all of them seems to segfault with floats and doubles)
:(

Thanks in advance,

--ghe
Anders Magnusson
2012-01-17 17:40:25 UTC
Permalink
Hm, strange. I tried it on Ubuntu 10.04 LTS and it worked fine.

Can you provide me with -S of this compiled with both gcc and pcc?

-- Ragge
Post by g***@sdf.org
Hi list,
I try to compile a very simple program with pcc (on Debian, AMD64,
int main () { printf ("%.10f", 10.0); return 0; }
$ pcc foo.c
$ ./a.out
Segmentation fault
$ gdb a.out
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main ()
Is there a way to make this work? I tried various alternatives
(sprintf, fprintf, etc.), but all of them seems to segfault with
floats and doubles) :(
Thanks in advance,
--ghe
g***@sdf.org
2012-01-17 22:34:53 UTC
Permalink
Post by Anders Magnusson
Hm, strange. I tried it on Ubuntu 10.04 LTS and it worked fine.
Can you provide me with -S of this compiled with both gcc and pcc?
Yes, they are attached to this mail. I tried this with both pcc
1.1.0.DEVEL 20111115 and 1.1.0.DEVEL 20120105, and both failed. In case
this is important, both were configured with:

./configure --prefix=$HOME/local/opt/pcc
./configure --prefix=$HOME/local/opt/pcc --with-libdir=$HOME/local/opt/pcc/lib/pcc/x86_64-unknown-linux-gnu/1.1.0.DEVEL/lib

Thanks in advance!

--ghe
Fred J. Tydeman
2012-01-17 18:43:10 UTC
Permalink
Post by g***@sdf.org
int main () { printf ("%.10f", 10.0); return 0; }
I do not see: #include <stdio.h>
Therefore, the compiler is missing the prototype of printf().
Since printf() is a varargs function, I would expect
strange things to happen.


---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Thorsten Glaser
2012-01-17 19:39:46 UTC
Permalink
Post by Fred J. Tydeman
Therefore, the compiler is missing the prototype of printf().
Since printf() is a varargs function, I would expect
strange things to happen.
Argument promotion is well-defined.

bye,
//mirabilos
--
“Having a smoking section in a restaurant is like having
a peeing section in a swimming pool.”
-- Edward Burr
g***@sdf.org
2012-01-17 22:36:43 UTC
Permalink
Post by Fred J. Tydeman
Post by g***@sdf.org
int main () { printf ("%.10f", 10.0); return 0; }
I do not see: #include <stdio.h>
Therefore, the compiler is missing the prototype of printf().
Since printf() is a varargs function, I would expect
strange things to happen.
Obviously this is one of the various things I tried. With or without
#include (who both generate the same assembly code, by the way), with
printf, fprintf, sprintf: nothing worked.

--ghe
Gregory McGarry
2012-01-19 07:09:13 UTC
Permalink
It may be a problem with the startup code. A disassembly when it
crashes might indicate what's happening. It's quite likely if you
haven't compiled libpcc and friends for a long while.
-------- Original Message --------
Subject: Re: printf error...
Date: Tue, January 17, 2012 2:34 pm
Post by Anders Magnusson
Hm, strange. I tried it on Ubuntu 10.04 LTS and it worked fine.
Can you provide me with -S of this compiled with both gcc and pcc?
Yes, they are attached to this mail. I tried this with both pcc
1.1.0.DEVEL 20111115 and 1.1.0.DEVEL 20120105, and both failed. In case
./configure --prefix=$HOME/local/opt/pcc
./configure --prefix=$HOME/local/opt/pcc --with-libdir=$HOME/local/opt/pcc/lib/pcc/x86_64-unknown-linux-gnu/1.1.0.DEVEL/lib
Thanks in advance!
--ghe
g***@sdf.org
2012-01-19 09:16:56 UTC
Permalink
Post by Gregory McGarry
It may be a problem with the startup code. A disassembly when it
crashes might indicate what's happening.
It follows...
Post by Gregory McGarry
It's quite likely if you haven't compiled libpcc and friends for a long
while.
No, that's not the problem. I compiled libpcc (what are his "friends"?) a
few minutes before using it, and it seems that everything went fine (at
least it did not signal an error).

----

$ pcc -g foo.c
$ gdb a.out
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...done.
(gdb) run
Starting program: a.out

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main () at foo.c:1
(gdb) frame 0
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 in printf.c
(gdb) disassemble
Dump of assembler code for function __printf:
0x00007ffff7aa6130 <+0>: sub $0xd8,%rsp
0x00007ffff7aa6137 <+7>: movzbl %al,%eax
0x00007ffff7aa613a <+10>: mov %rdx,0x30(%rsp)
0x00007ffff7aa613f <+15>: lea 0x0(,%rax,4),%rdx
0x00007ffff7aa6147 <+23>: lea 0x44(%rip),%rax # 0x7ffff7aa6192 <__printf+98>
0x00007ffff7aa614e <+30>: mov %rsi,0x28(%rsp)
0x00007ffff7aa6153 <+35>: mov %rcx,0x38(%rsp)
0x00007ffff7aa6158 <+40>: mov %rdi,%rsi
0x00007ffff7aa615b <+43>: sub %rdx,%rax
0x00007ffff7aa615e <+46>: lea 0xcf(%rsp),%rdx
0x00007ffff7aa6166 <+54>: mov %r8,0x40(%rsp)
0x00007ffff7aa616b <+59>: mov %r9,0x48(%rsp)
0x00007ffff7aa6170 <+64>: jmpq *%rax
0x00007ffff7aa6172 <+66>: movaps %xmm7,-0xf(%rdx)
0x00007ffff7aa6176 <+70>: movaps %xmm6,-0x1f(%rdx)
0x00007ffff7aa617a <+74>: movaps %xmm5,-0x2f(%rdx)
0x00007ffff7aa617e <+78>: movaps %xmm4,-0x3f(%rdx)
0x00007ffff7aa6182 <+82>: movaps %xmm3,-0x4f(%rdx)
0x00007ffff7aa6186 <+86>: movaps %xmm2,-0x5f(%rdx)
0x00007ffff7aa618a <+90>: movaps %xmm1,-0x6f(%rdx)
=> 0x00007ffff7aa618e <+94>: movaps %xmm0,-0x7f(%rdx)
0x00007ffff7aa6192 <+98>: lea 0xe0(%rsp),%rax
0x00007ffff7aa619a <+106>: mov %rsp,%rdx
0x00007ffff7aa619d <+109>: movl $0x8,(%rsp)
0x00007ffff7aa61a4 <+116>: movl $0x30,0x4(%rsp)
0x00007ffff7aa61ac <+124>: mov %rax,0x8(%rsp)
0x00007ffff7aa61b1 <+129>: lea 0x20(%rsp),%rax
0x00007ffff7aa61b6 <+134>: mov %rax,0x10(%rsp)
0x00007ffff7aa61bb <+139>: mov 0x330d4e(%rip),%rax # 0x7ffff7dd6f10
0x00007ffff7aa61c2 <+146>: mov (%rax),%rdi
0x00007ffff7aa61c5 <+149>: callq 0x7ffff7a9b3c0 <_IO_vfprintf_internal>
0x00007ffff7aa61ca <+154>: add $0xd8,%rsp
0x00007ffff7aa61d1 <+161>: retq
End of assembler dump.
(gdb) frame 1
#1 0x000000000040049d in main () at foo.c:1
1 int main () { printf ("%.10f", 10.0); return 0; }
(gdb) disassemble
Dump of assembler code for function main:
0x0000000000400474 <+0>: push %rbp
0x0000000000400475 <+1>: mov %rsp,%rbp
0x0000000000400478 <+4>: sub $0x10,%rsp
0x000000000040047c <+8>: mov $0x4004e0,%rax
0x0000000000400483 <+15>: mov %rax,-0x8(%rbp)
0x0000000000400487 <+19>: movsd 0x59(%rip),%xmm0 # 0x4004e8
0x000000000040048f <+27>: mov -0x8(%rbp),%rdi
0x0000000000400493 <+31>: mov $0x1,%eax
0x0000000000400498 <+36>: callq 0x400340 <***@plt>
=> 0x000000000040049d <+41>: movl $0x0,-0xc(%rbp)
0x00000000004004a4 <+48>: jmp 0x4004a6 <main+50>
0x00000000004004a6 <+50>: mov -0xc(%rbp),%eax
0x00000000004004a9 <+53>: leaveq
0x00000000004004aa <+54>: retq
End of assembler dump.
(gdb) quit
g***@sdf.org
2012-01-19 11:46:54 UTC
Permalink
Post by g***@sdf.org
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main () at foo.c:1
What's the value of %rsp?
Joerg
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) info registers
rax 0x7ffff7aa618e 140737348526478
rbx 0x7fffffffe318 140737488347928
rcx 0x0 0
rdx 0x7fffffffe2a7 140737488347815
rsi 0x4004e0 4195552
rdi 0x4004e0 4195552
rbp 0x7fffffffe2c8 0x7fffffffe2c8
rsp 0x7fffffffe1d8 0x7fffffffe1d8
r8 0x7ffff7dd8320 140737351877408
r9 0x0 0
r10 0x0 0
r11 0x7ffff7aa6130 140737348526384
r12 0x1 1
r13 0x7fffffffe300 140737488347904
r14 0x0 0
r15 0x0 0
rip 0x7ffff7aa618e 0x7ffff7aa618e <__printf+94>
eflags 0x10216 [ PF AF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
Joerg Sonnenberger
2012-01-19 11:35:58 UTC
Permalink
Post by g***@sdf.org
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main () at foo.c:1
What's the value of %rsp?

Joerg
Joerg Sonnenberger
2012-01-19 17:37:19 UTC
Permalink
Post by g***@sdf.org
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main () at foo.c:1
(gdb) frame 0
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 in printf.c
0x00007ffff7aa6130 <+0>: sub $0xd8,%rsp
0x00007ffff7aa6137 <+7>: movzbl %al,%eax
0x00007ffff7aa613a <+10>: mov %rdx,0x30(%rsp)
0x00007ffff7aa613f <+15>: lea 0x0(,%rax,4),%rdx
0x00007ffff7aa6147 <+23>: lea 0x44(%rip),%rax # 0x7ffff7aa6192 <__printf+98>
0x00007ffff7aa614e <+30>: mov %rsi,0x28(%rsp)
0x00007ffff7aa6153 <+35>: mov %rcx,0x38(%rsp)
0x00007ffff7aa6158 <+40>: mov %rdi,%rsi
0x00007ffff7aa615b <+43>: sub %rdx,%rax
0x00007ffff7aa615e <+46>: lea 0xcf(%rsp),%rdx
%rsp is 0x7fffffffe1d8
Post by g***@sdf.org
0x00007ffff7aa6166 <+54>: mov %r8,0x40(%rsp)
0x00007ffff7aa616b <+59>: mov %r9,0x48(%rsp)
0x00007ffff7aa6170 <+64>: jmpq *%rax
0x00007ffff7aa6172 <+66>: movaps %xmm7,-0xf(%rdx)
0x00007ffff7aa6176 <+70>: movaps %xmm6,-0x1f(%rdx)
0x00007ffff7aa617a <+74>: movaps %xmm5,-0x2f(%rdx)
0x00007ffff7aa617e <+78>: movaps %xmm4,-0x3f(%rdx)
0x00007ffff7aa6182 <+82>: movaps %xmm3,-0x4f(%rdx)
0x00007ffff7aa6186 <+86>: movaps %xmm2,-0x5f(%rdx)
0x00007ffff7aa618a <+90>: movaps %xmm1,-0x6f(%rdx)
=> 0x00007ffff7aa618e <+94>: movaps %xmm0,-0x7f(%rdx)
...so this is effectively %7fffffffe228, which is not properly aligned.
I'm curious why it traps at this point, when it should fail earlier
already...

Since the stack frame has the correct size of 8 mod 16, it means
something in your call chain is not keeping the stack aligned correctly.

Joerg
g***@sdf.org
2012-01-19 22:28:41 UTC
Permalink
Post by Joerg Sonnenberger
...so this is effectively %7fffffffe228, which is not properly aligned.
I'm curious why it traps at this point, when it should fail earlier
already...
Since the stack frame has the correct size of 8 mod 16, it means
something in your call chain is not keeping the stack aligned correctly.
Okay... But what can I do to help you further?

Just in case, I attached the a.out file to this mail. Maybe it contains
some information decryptable by you?

Thanks,

--ghe
g***@sdf.org
2012-05-19 11:57:46 UTC
Permalink
Hi list,

I still try to compile some very simple programs with pcc (on Debian,
AMD64), without luck:

test1.c: int main () { printf ("10\n"); return 0; }
test2.c: int main () { printf ("%d\n", 10); return 0; }
test3.c: int main () { printf ("%.1f\n", 10.0); return 0; }

I tried to check the previous versions of PCC, to see whether it has ever
worked, and the answer seems to be negative.

Support for 64 bit systems was added in version 090815, and in that
version test1.c and test2.c work, but test3.c does not (it segfaults in
printf).

Three days later, in version 090817, none of those three tests works any
more (they segfault), although the output of pcc -S has not changed.

The two first tests start to work again with version 20110413, but again
the output of pcc -S does not change between versions 20110412 and
20110413.

In the latest CVS sources (version 20120519) the situation is still the
same: the two first tests work, but not the third one (it segfaults in
printf).

The output of tcc -S for the different versions is attached to this mail.
It seems that the problem is not in the code generated by pcc, however:
those assembly files produce the expected output when they are compiled
with gcc. So my guess is that something is wrong in pcc-libs.

Please let me know what other information I can/should provide to have
this bug fixed.

--ghe
Fred J. Tydeman
2012-05-19 14:31:30 UTC
Permalink
Post by g***@sdf.org
test1.c: int main () { printf ("10\n"); return 0; }
test2.c: int main () { printf ("%d\n", 10); return 0; }
test3.c: int main () { printf ("%.1f\n", 10.0); return 0; }
You are missing
#include <stdio.h> /* printf() */

Since printf() is a varargs function, not having a prototype
in scope means undefined behaviour.

In addition, C99 removed implicit function declaration.

Also, it should be
int main(void){ .... }


---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
g***@sdf.org
2012-05-19 15:39:51 UTC
Permalink
Post by Fred J. Tydeman
Post by g***@sdf.org
test1.c: int main () { printf ("10\n"); return 0; }
test2.c: int main () { printf ("%d\n", 10); return 0; }
test3.c: int main () { printf ("%.1f\n", 10.0); return 0; }
You are missing
#include <stdio.h> /* printf() */
Since printf() is a varargs function, not having a prototype in scope
means undefined behaviour.
In addition, C99 removed implicit function declaration.
Also, it should be
int main(void){ .... }
I'm sorry, but this is not really helpful, it's already what you replied
in January, when I first mentioned the bug on the list... These three
examples were not meant to be examples of perfectly conformant ANSI C, but
stripped down examples to demonstrate the bug.

So I can only restate my answer: Obviously this is one of the various
things I tried. With or without #include (who both generate the same
assembly code, by the way), with printf, fprintf, sprintf: nothing worked.

By the way, these three files compile and work perfectly well with any
decent C compiler (GCC, SunCC, OpenCC, TCC, ICC, etc., and PCC on i386),
even though a warning is generated.

--ghe
Mike
2012-05-19 17:27:08 UTC
Permalink
It worked for me on M$ Windows.
Post by g***@sdf.org
int main () { printf ("%.1f\n", 10.0); return 0; }
g***@sdf.org
2012-06-10 17:39:54 UTC
Permalink
Hi list,

Here follow the exact steps I do to reproduce the printf + doubles bug:

mkdir $HOME/pccbug
cd $HOME/pccbug
wget -O pcc-libs.tar.gz http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/pcc-libs-20120609.tgz
tar xfz pcc-libs.tar.gz
mv pcc-libs-20120609 pcc-libs
cd pcc-libs
./configure --prefix=$HOME/pccbug
make
make install
cd ..
wget -O pcc.tar.gz http://pcc.ludd.ltu.se/ftp/pub/pcc/pcc-20120609.tgz
tar xfz pcc.tar.gz
mv pcc-20120609 pcc
cd pcc
./configure --prefix=$HOME/pccbug --with-libdir=$HOME/pccbug/lib/pcc/x86_64-unknown-linux-gnu/1.1.0.DEVEL/lib
make
make install
cd ..
cd bin
cat << EOF > test.c
#include <stdio.h>
int main () { return printf ("%.10f\n", 10.0); }
EOF
./pcc -o test test.c
./test

It segfaults at least with:

- GCC 4.4.6 or 4.5.3 or 4.6.1 on Debian Testing
- GCC 3.4.6 or 4.6.3 on Fedora release 16

Thanks,

--ghe
Anders Magnusson
2012-06-10 19:13:01 UTC
Permalink
Hi, and I just tested this.

- It works on FreeBSD 10.0-CURRENT
- It do NOT work on Ubuntu 10.04.4 LTS

but...

If you compile with pcc and link with gcc it works(!). So it's
something in how linking is done that is wrong. Hm...

-- Ragge
Post by g***@sdf.org
Hi list,
mkdir $HOME/pccbug
cd $HOME/pccbug
wget -O pcc-libs.tar.gz
http://pcc.ludd.ltu.se/ftp/pub/pcc-libs/pcc-libs-20120609.tgz
tar xfz pcc-libs.tar.gz
mv pcc-libs-20120609 pcc-libs
cd pcc-libs
./configure --prefix=$HOME/pccbug
make
make install
cd ..
wget -O pcc.tar.gz http://pcc.ludd.ltu.se/ftp/pub/pcc/pcc-20120609.tgz
tar xfz pcc.tar.gz
mv pcc-20120609 pcc
cd pcc
./configure --prefix=$HOME/pccbug
--with-libdir=$HOME/pccbug/lib/pcc/x86_64-unknown-linux-gnu/1.1.0.DEVEL/lib
make
make install
cd ..
cd bin
cat << EOF > test.c
#include <stdio.h>
int main () { return printf ("%.10f\n", 10.0); }
EOF
./pcc -o test test.c
./test
- GCC 4.4.6 or 4.5.3 or 4.6.1 on Debian Testing
- GCC 3.4.6 or 4.6.3 on Fedora release 16
Thanks,
--ghe
Iain Hibbert
2012-06-11 16:46:28 UTC
Permalink
Post by Anders Magnusson
Hi, and I just tested this.
- It works on FreeBSD 10.0-CURRENT
- It do NOT work on Ubuntu 10.04.4 LTS
but...
If you compile with pcc and link with gcc it works(!). So it's something in
how linking is done that is wrong. Hm...
My suggestion would be to look at the linker arguments as shown by "gcc
-v" vs "pcc -v"; perhaps gcc includes something that is not provided by
the os/linux/ccconfig.h file.. something that provides a constructor that
remains uninitialised?

regards,
iain
Fred J. Tydeman
2012-06-15 17:16:23 UTC
Permalink
Code similar to the following causes pcc to die on a 64-bit
version of Fedora Core Linux on an Intel Core CPU, but no
such death happens on a 32-bit version (instead death
happens at runtime). I contend that % is defined independent
of /, so there should not be undefined behaviour here.

/* (M % -1) == 0 for all M */
#include <limits.h>
static long int li = (LONG_MIN % -1L);
extern long int lix = (LONG_MIN % -1L);
int main(void){
long int li2 = LONG_MIN;
long int li3 = LONG_MIN % -1L;
return (li == lix) && (li3 == (li2 % -1L)) && (li3 == 0L);
}


---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Fred J. Tydeman
2012-06-15 17:26:00 UTC
Permalink
Post by Fred J. Tydeman
I contend that % is defined independent
of /, so there should not be undefined behaviour here.
On re-reading the entire section on % in the C standard,
I see that I was wrong.

Section 6.5.5 Multiplicative operators, paragraph 6

If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a; otherwise, the behavior
of both a/b and a%b is undefined.

So, ignore my previous posting.

---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Thorsten Glaser
2012-06-15 21:35:15 UTC
Permalink
Post by Fred J. Tydeman
Code similar to the following causes pcc to die on a 64-bit
version of Fedora Core Linux on an Intel Core CPU, but no
such death happens on a 32-bit version (instead death
happens at runtime). I contend that % is defined independent
of /, so there should not be undefined behaviour here.
That’s actually a bug in many CPUs which people need to work around.
In mksh, I’ve got a configure (build+run) time check whether doing
an integer division and modulo of the largest negative integer with
-1 both works (or gets things like SIGFPE) and has the expected result
(you wouldn’t believe how many CPUs return false values for this… m68k,
sparc, powerpc among them).

In short, no matter on what the standard says, you cannot rely on the
system (compile OR runtime) to do 0x8000…0 / -1 right, at all.

bye,
//mirabilos
--
21:27⎜[Natureshadow] BÄH! Wer hatn das Bier neben den Notebooklüfter
⎜ gestellt ...
21:27⎜>Natureshadow< lol 21:27⎜>Natureshadow< du?
21:27⎜[Natureshadow] vermutlich ... -- Kev^WNatureshadow allein zu Haus
Fred J. Tydeman
2012-06-16 02:44:03 UTC
Permalink
The following code (which should be strictly conforming C)
works fine with gcc and clang on Fedora Core Linux 16 on
an Intel Core CPU. But, it dies with pcc.


#define DEBUG344(m) { (void)printf("Doing %i\n",m); fflush(NULL); }
#include <limits.h>
#include <stdio.h>
int main(void){
#if (LONG_MAX < LLONG_MAX) || (LONG_MIN == -(LONG_MAX))
signed long long int slli;
signed long int sli;
DEBUG344(1);
slli = LONG_MIN;
slli %= -1LL; /* OK */
DEBUG344(2);
sli = LONG_MIN;
sli %= -1LL; /* Dies here; promotion to long long not done. */
DEBUG344(3);
#else
DEBUG344(4);
#endif
return 0;
}


---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Anders Magnusson
2012-06-18 14:57:38 UTC
Permalink
Hi Fred,

can you reference that the behavior in your code below is conforming?

An assignment like
int i;
long j;

i += j;

is said in 6.5.16 clause 3 that the resulting type is that of the left
operand but not that any type promotion with following truncation is
done on the left op in the addition. I cannot find anything anywhere
that says that the left op should be promoted.

pcc do not promote anything here and has never done. In fact; this code
is usually converted to just one instruction on targets like i386.

-- Ragge
Post by Fred J. Tydeman
The following code (which should be strictly conforming C)
works fine with gcc and clang on Fedora Core Linux 16 on
an Intel Core CPU. But, it dies with pcc.
#define DEBUG344(m) { (void)printf("Doing %i\n",m); fflush(NULL); }
#include <limits.h>
#include <stdio.h>
int main(void){
#if (LONG_MAX < LLONG_MAX) || (LONG_MIN == -(LONG_MAX))
signed long long int slli;
signed long int sli;
DEBUG344(1);
slli = LONG_MIN;
slli %= -1LL; /* OK */
DEBUG344(2);
sli = LONG_MIN;
sli %= -1LL; /* Dies here; promotion to long long not done. */
DEBUG344(3);
#else
DEBUG344(4);
#endif
return 0;
}
---
Fred J. Tydeman Tydeman Consulting
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Fred J. Tydeman
2012-06-18 15:52:10 UTC
Permalink
Post by Anders Magnusson
Hi Fred,
can you reference that the behavior in your code below is conforming?
An assignment like
int i;
long j;
i += j;
is said in 6.5.16 clause 3 that the resulting type is that of the left operand
but not that any type promotion with following truncation is done on the left
op in the addition. I cannot find anything anywhere that says that the left
op should be promoted.
pcc do not promote anything here and has never done. In fact; this code is
usually converted to just one instruction on targets like i386.
Looking at WG14 / N1569 (C11)
6.5.16.2 Compound assignment
Paragraph 3
A compound assignment of the form E1 op = E2 is equivalent to the simple assignment
expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with
respect to an indeterminately-sequenced function call, the operation of a compound
assignment is a single evaluation.


---
Fred J. Tydeman Tydeman Consulting
***@tybor.com Testing, numerics, programming
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Anders Magnusson
2012-06-18 16:39:40 UTC
Permalink
Post by Fred J. Tydeman
Post by Anders Magnusson
Hi Fred,
can you reference that the behavior in your code below is conforming?
An assignment like
int i;
long j;
i += j;
is said in 6.5.16 clause 3 that the resulting type is that of the left operand
but not that any type promotion with following truncation is done on the left
op in the addition. I cannot find anything anywhere that says that the left
op should be promoted.
pcc do not promote anything here and has never done. In fact; this code is
usually converted to just one instruction on targets like i386.
Looking at WG14 / N1569 (C11)
6.5.16.2 Compound assignment
Paragraph 3
A compound assignment of the form E1 op = E2 is equivalent to the simple assignment
expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with
respect to an indeterminately-sequenced function call, the operation of a compound
assignment is a single evaluation.
Great, thanks! I'll fix it.

-- Ragge
Anders Magnusson
2012-06-20 20:08:36 UTC
Permalink
So, bug fixed, thanks!

-- Ragge
Post by Fred J. Tydeman
Post by Anders Magnusson
Hi Fred,
can you reference that the behavior in your code below is conforming?
An assignment like
int i;
long j;
i += j;
is said in 6.5.16 clause 3 that the resulting type is that of the left operand
but not that any type promotion with following truncation is done on the left
op in the addition. I cannot find anything anywhere that says that the left
op should be promoted.
pcc do not promote anything here and has never done. In fact; this code is
usually converted to just one instruction on targets like i386.
Looking at WG14 / N1569 (C11)
6.5.16.2 Compound assignment
Paragraph 3
A compound assignment of the form E1 op = E2 is equivalent to the simple assignment
expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with
respect to an indeterminately-sequenced function call, the operation of a compound
assignment is a single evaluation.
---
Fred J. Tydeman Tydeman Consulting
+1 (775) 358-9748 Vice-chair of PL22.11 (ANSI "C")
Sample C99+FPCE tests: http://www.tybor.com
Savers sleep well, investors eat well, spenders work forever.
Anders Magnusson
2012-09-20 19:40:30 UTC
Permalink
After a reaaaaaally long time I have at last fixed this bug... at least
it works for me now.

-- Ragge
Post by g***@sdf.org
Hi list,
I try to compile a very simple program with pcc (on Debian, AMD64,
int main () { printf ("%.10f", 10.0); return 0; }
$ pcc foo.c
$ ./a.out
Segmentation fault
$ gdb a.out
GNU gdb (GDB) 7.2-debian
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
30 printf.c: No such file or directory.
in printf.c
(gdb) bt
#0 0x00007ffff7aa618e in __printf (format=0x4004e0 "%.10f") at printf.c:30
#1 0x000000000040049d in main ()
Is there a way to make this work? I tried various alternatives
(sprintf, fprintf, etc.), but all of them seems to segfault with
floats and doubles) :(
Thanks in advance,
--ghe
Loading...