bug

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Oct 11 03:07:45 PDT 2007


I have a bug in lib std.c.stdio wrote:
> When I run this application, it show this information.
> hello world
> args.length = 1
> args[0] = 'D:\Test\bin\Release
> Error: Access Violation

(By the way, I think you either filled in the boxes wrong or you're 
using a really weird name :P)

This bug isn't related to D. Your program also crashes when translated to C:
---
#include <stdio.h>

int main(size_t argc, char** argv)
{
     printf("hello world\n");
     printf("args.length = %d\n", argc);
     for (int i = 0; i < argc; i++)
         printf("args[%d] = '%s'\n", i, argv[i]);
     FILE* file = NULL;
//    file=fopen("input.txt","r");
     freopen("input.txt","r", file);
     int a;
     fscanf(file,"%d",&a);
     printf("%d",a);
     return 0;
}
---
(Note that D automatically initializes pointers to null, so I did so 
explicitly in the C version. If I hadn't done that it'd be accessing an 
invalid (uninitialized) pointer)
freopen() expects a valid FILE* pointer as its third argument, not an 
uninitialized one or NULL. Why aren't you just using fopen() as in the 
commented line? (That works fine in both the D and the C version)

Also, std.c.stdio isn't really something you should be using when 
working with D. For example, your printf is bad:
     printf("args[%d] = '%s'\n", i, cast(char *)args[i]);
That cast takes a pointer to the first element of a char[] that's not 
guaranteed to be null-terminated (though it probably is, but only 
because the D runtime passes in a slice of the C argument string). If 
you insist on using printf, lose the cast and change the format string 
to end in '%.*s'\n. That way, the length of the string is passed and 
used by printf.
A much better way would be to
     import std.stdio;
     writefln("args[%d] = '%s'", i, args[i]);
This is typesafe, and the format strings can be simpler (for instance, 
the %d could be replaced by %s and it'd still do the same).

Unfortunately Phobos currently doesn't have a good replacement for the 
*scanf() family, so that could be a bit trickier.


Cross-posted and followup set to digitalmars.D.learn, which is more 
appropriate.


More information about the Digitalmars-d-learn mailing list