April 25, 2006
On Tue, 25 Apr 2006 15:51:03 +0800, Boris Wang <nano.kago@hotmail.com> wrote:
> "Regan Heath" <regan@netwin.co.nz>
> ??????:ops8jx4rqc23k2f5@nrage.netwin.co.nz...
>> On Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago@hotmail.com>
>> wrote:
>>> You are right, the args array begin from index 0, but
>>>
>>>>   foreach( char[] arg; args[0 .. args.length] )
>>>
>>> This should not be right, it should be :
>>>     foreach( char[] arg; args[0 .. args.length - 1] )
>>
>> That is not true.
>>
>> In D, arrays are indexed from 0 and when slicing the start index is
>> inclusive and the end index is not. Meaning, for example that:
>>
>> args[0..2]
>>
>> is a slice of items 0, and 1, but _not_ 2. If you use args.length-1 you
>> will _not_ include the last item of the array in the slice. If you want
>> the whole array then the end index must be the array length (AKA the index
>> of the item past the end of the array)
>>
>>> and more, when i run the followed code:
>>>
>>> import std.stdio;
>>>
>>> int main( char[][] args )
>>> {
>>>  foreach( char[] arg; args[0 .. args.length - 1 ] )
>>>  {
>>>   printf( "%s ", cast(char*)arg );
>>>  }
>>> }
>>>
>>> it even produce a assert:
>>>
>>> Error: AssertError Failure hello_my.d(10)
>>
>> The assert has nothing to do with the array slice and everything to do
>> with the missing return value in main. Try:
>>
>> import std.stdio;
>>
>> int main( char[][] args )
>> {
>>  foreach( char[] arg; args[0 .. args.length] )
>>  {
>>   printf( "%s ", cast(char*)arg );
>>  }
>>  return 0;
>> }
>>
>
> Why not a complie error, but a runtime error?

I believe the rationale is that it is not possible for the compiler to detect all possible situations with 100% certainty. I suspect Walter came to that conclusion adding this sort of compile time detection to his C/C++ compiler.

Regan
April 25, 2006
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Jarrett Billingsley schrieb am 2006-04-25:
> 
>>"Boris Wang" <nano.kago@hotmail.com> wrote in message news:e2k46n$1dkm$1@digitaldaemon.com...
>>
>>>The first printf can't display the information, and the second do.
>>
>>Uhh, yes it does.  For me, anyway.
>>
>>But I think the real question here is - why are you using printf instead of writef?  ;)
> 
> 
> <snip>
> 
>> for ( int i = 1; i < args.length; i++ )
>> {
>>  writef( args[i], ' ' );
>> }
> 
> 
> That's usually not a good idea(unchecked format strings...), instead use:
> 
> for ( int i = 1; i < args.length; i++ )
> {
> 	writef("%s ", args[i]);
> }
> 
> Thomas
> 
> 
> -----BEGIN PGP SIGNATURE-----
> 
> iD8DBQFETcyD3w+/yD4P9tIRAoLlAJsHZWWhbEADKVfC3blCpG0cY9HStwCeNWZZ
> IL9fNNCb5TazTmklf8blE3c=
> =nRGq
> -----END PGP SIGNATURE-----

or

writef( arg ~ ' ' );
April 25, 2006
Thomas Kuehne wrote:
> That's usually not a good idea(unchecked format strings...)

Huh? In what kind of situation are the following two not equivalent?

writef("%s", s);
writef(s);

Regardless of the type of s, these surely work the same way, right?

Some test code to argue my point:

--
import std.stdio;

template func(TYPE) { void func(TYPE s) {
	writef("'", s, "'");
	writef(" and ");
	writef("'%s'", s);
	writefln();
}}

class Foo {
	char[] toString() { return "fooclass"; }
}

void main() {
	func("asdf");
	func(1234);
	func(true);
	func('n');
	func(0.1234);
	func(new Foo());
}
--

In func's output, what's on the left side of the "and" is the same as on the right, in all six cases.
April 25, 2006
Deewiant wrote:
> Thomas Kuehne wrote:
>> That's usually not a good idea(unchecked format strings...)
> 
> Huh? In what kind of situation are the following two not equivalent?
> 
> writef("%s", s);
> writef(s);
> 
> Regardless of the type of s, these surely work the same way, right?
> 
> Some test code to argue my point:
> 
> --
> import std.stdio;
> 
> template func(TYPE) { void func(TYPE s) {
> 	writef("'", s, "'");
> 	writef(" and ");
> 	writef("'%s'", s);
> 	writefln();
> }}
> 
> class Foo {
> 	char[] toString() { return "fooclass"; }
> }
> 
> void main() {
> 	func("asdf");
> 	func(1234);
> 	func(true);
> 	func('n');
> 	func(0.1234);
> 	func(new Foo());
> }
> --
> 
> In func's output, what's on the left side of the "and" is the same as on the
> right, in all six cases.

func("%s%s%s");

:)


xs0
April 25, 2006
Deewiant wrote:

>>That's usually not a good idea(unchecked format strings...)
> 
> Huh? In what kind of situation are the following two not equivalent?

When the string contains format characters (that would be '%')

> writef("%s", s);
> writef(s);
> 
> Regardless of the type of s, these surely work the same way, right?

import std.stdio;
void main()
{
  char[] s = "100%";
  writef(s);
}

==> Throws an error:
100Error: std.format invalid specifier

import std.stdio;
void main()
{
  char[] s = "100%";
  writef("%s", s);
}

==> This works OK.

I suggested adding a function "write", that *didn't* parse for format
characters (and the matching "writeln" function), but it was ignored...

import std.stdio;
void main()
{
  char[] s = "100%";
  write(s);
}

http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/15627

--anders
April 25, 2006
Anders F Björklund wrote:
> When the string contains format characters (that would be '%')
> 

Ah, of course. Thanks for reminding me, to xs0 as well.
April 25, 2006
Deewiant wrote:

>>When the string contains format characters (that would be '%')
> 
> Ah, of course. Thanks for reminding me, to xs0 as well.

Printf has the same problem. I bet you could trigger some
real nice buffer overflows by abusing this "feature"...

IMNSHO:
Telling newcomers to use printf("Hello") or writef("World")
will just make them shoot themselves in the foot later on.

Whenever you introduce either, you need to talk about "formats".
Which is why it's better if there's an alternative *without* ?

Like in C:
#include <stdio.h>
int main(int argc, char* argv[])
{
  puts("Hello, World!");
  return 0;
}

But that's just what I thought about the issue, nothing new.
(And no, it's not a problem for strings without the percent)

--anders
April 25, 2006
In article <6uu0i3-m2i.ln1@birke.kuehne.cn>, Thomas Kuehne says...
>Jarrett Billingsley schrieb am 2006-04-25:
>>  for ( int i = 1; i < args.length; i++ )
>>  {
>>   writef( args[i], ' ' );
>>  }
>
>That's usually not a good idea(unchecked format strings...), instead use:
>
>for ( int i = 1; i < args.length; i++ )
>{
>	writef("%s ", args[i]);
>}
>
>Thomas

This has bit me more than once. Maybe there should be a writef that won't do
formatting (writefn("%s", 123); prints "%s123")


1 2
Next ›   Last »