Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1956 (new defect)

Opened 14 years ago

Last modified 14 years ago

sscanf with format %f crashes program

Reported by: HeiHon Assigned to: community
Priority: major Milestone: 1.0
Component: Tango Version: 0.99.9 Kai
Keywords: scanf float Cc:

Description

dmd 1.062 / tango-r5498 / WinXP32 SP3:

Using sscanf with a floating point format specifier (%f, %g..) crashes the program.

The program compiles and links happily, but it crashes at runtime. sscanf with %d works.

I played a bit with conversion from string to float and found some issues with text.convert.Float and util.Convert, so I tried sscanf.

With tango it crashes the program. Trying sscanf with Phobos worked. Trying sscanf with pure C/Digital Mars C Compiler worked.

I attached a ZIP with conv_c.c (C program), conv_phobos.d (D with Phobos) and conv_tango (D with Tango) and output files conv_tango.txt (running conv_tango with sscanf and format %d) and conv_tango_-float.txt (running conv_tango with sscanf and format %f).

I read something about float.d not beeing available, but even if this lack of support is by purpose, it should not crash the program. It should throw instead. Anyway, Phobos has support for floating point format with sscanf.

Attachments

sscanf.zip (2.1 kB) - added by HeiHon on 07/12/10 14:42:42.
ZIP with test programs and output files
convno.d (1.9 kB) - added by HeiHon on 07/16/10 09:25:43.
Test program for string to float conversion

Change History

07/12/10 14:42:42 changed by HeiHon

  • attachment sscanf.zip added.

ZIP with test programs and output files

07/12/10 15:29:42 changed by torhu

Work fine when I try it. DMD 1.061, Tango 0.99.9 on Windows 7.

Looks a bit like the issue someone posted here: http://www.digitalmars.com/d/archives/digitalmars/D/Floating_point_not_loaded_112016.html

Could be something with your setup, maybe.

07/12/10 19:35:02 changed by mwarning

It works for me on linux (dmd 32bit and ldc 64bit). Here is a shorter test case:

import Stdc = tango.stdc.stdio;

void main()
{
  float x;
  Stdc.sscanf("-.", "%f", &x);
}

On WinXP(SP3), dmd 1.062 (in MinGW32) and tango trunk I get the same error message: "Floating point not loaded"

sscanf is a C function exposed by Tango, so it might have nothing to do with Tango at all. (Maybe dmc?)

07/13/10 09:17:42 changed by HeiHon

@torhu:

Thanks for pointing me there.

I don't think that it's something with my setup: Compile/link/run of a similar D program with dmd+phobos did work. And compile/link/run of a similar C program with dmc also worked.

Anyway: After changing my sc.ini so that I have to specify all libs (except tango.lib) at the command line and building with

dmd conv_tango.d -L+D:\dmd\windows\lib\snn.lib

did work.

BTW: The program compiled and linked happily without snn.lib, but then it crashed at runtime. And a mere

pragma(lib, "snn.lib");

did not do the trick. With or without pragma(lib..) the exe file had a size of 161308 byte. With -L+snn.lib at the command line the exe file had a size of 180252 byte and worked.

@mwarning:

That's why I included a dmd+phobos version and a C version compiled with dmc - both worked. But as I learned from the track torhu pointed at: dmc uses a different snn.lib.

07/13/10 11:01:04 changed by HeiHon

Actually this seems to be a dmd/windows-only bug:

With

pragma(lib, "snn.lib");

in the d file and doing

dmd conv_tango.d

I get a broken exe file with "Floating point not loaded". But the obj file has an entry

__fltused

in it. So, simply doing

dmd conv_tango.d
link conv_tango.obj

produces an exe file with the floating point stuff included.

So please feel free to close this ticket as a tango ticket.

07/13/10 16:11:41 changed by HeiHon

It seems a bit more complicated, though:

dmd 1.062 + tango-r5498 -> "Floating point not loaded"

dmd 1.061 + Tango 0.99.9 -> OK

dmd 1.062 + Tango 0.99.9 -> OK

dmd 1.061 + tango-r5498 -> "Floating point not loaded"

So it's somehow related to tango :-/

07/13/10 18:07:50 changed by HeiHon

And:

dmd 1.062 + tango-r5300 -> OK

dmd 1.062 + tango-r5400 -> "Floating point not loaded"

07/13/10 21:59:16 changed by mwarning

Interesting, maybe we can narrow it down to the commit in question.

07/15/10 11:08:19 changed by HeiHon

Yep:

dmd 1.062 + tango-r5396 -> OK

dmd 1.062 + tango-r5397 -> "Floating point not loaded"

07/15/10 12:23:47 changed by HeiHon

It's line 6 of

tango\core\rt\compiler\dmd\ignore.d

which (ignore.d) was introduced by r5397.

When I change line 6 to

        // void _fltused() {throw new Exception("fltused");}

the floating point stuff is included by dmd and the exe file size increases in my example (dmd 1.062 + tango-r5498) from 161308 byte to 171036 byte.

07/15/10 18:09:54 changed by kris

Yeah, this is kinda interesting.

DMD has a -nofloat flag, which is worthless when you use phobos since the latter drags in the full C I/O subsystem along with printf/scanf and a boatload of other bloat. The compiler author also claims that using an FP argument for Thread.sleep() would cause all the FP support to be dragged in, and thus forced druntime to be changed making it more incompatible with Tango. The latter is, of course, patently false (one merely has to look at the codegen to see why).

With r5379 we finally got fed up with the hidden bloat and set about removing it, without thinking about whether people would be using printf/scanf for FP arguments. Took a lot of effort to track down exactly what was dragging in all the unused code.

To resolve this I suspect we can comment out line 6 while leaving the other line intact. This should permit -nofloat to actually do something useful for the first time since it was introduced (4 years ago?)

HeiHon?: would you mind checking to see if -nofloat does indeed reduce the size of the executable in your test program (when line 6 is commented) ?

07/16/10 09:24:27 changed by HeiHon

So here it is (WinXP Pro SP3 / dmd 1.062 / tango-r5498 with line 6 commented out).

convno.d with sscanf(%f):

dmd convno.d                        -> 171036
dmd -nofloat convno.d               -> 171036
dmd -release -O convno.d            -> 167964
dmd -nofloat -release -O convno.d   -> 167964

When I use FP stuff, I think dmd *should* include it. So I removed the sscanf stuff (lines 4, 8, 18-21 and 27-28).

And got without sscanf(%f):

dmd convno.d                        -> 166428
dmd -nofloat convno.d               -> 166428
dmd -release -O convno.d            -> 163356
dmd -nofloat -release -O convno.d   -> 163356

Please see the attached convno.d test program.

07/16/10 09:25:43 changed by HeiHon

  • attachment convno.d added.

Test program for string to float conversion