www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unmatched static array size assignment

reply Andrej Mitrovic <none none.none> writes:
Code:

void main()
{
    static string[2] szFormat = ["%s, %s"];
}

This compiles, but this is buggy code. The first declaration should have been:
static string[2] szFormat = ["%s", "%s"];

I can't tell whether the first case is legit code. You might *want* to
initialize all the elements with the same single initializer. But in that case,
you would write:
static string[2] szFormat = "%s, ";

So, without the '[]'.

If you remove static from the declaration (it's still a static array, I know!),
you'll get a nice runtime error:
object.Exception src\rt\arraycat.d(31): lengths don't match for array copy

Actually it's not a nice error message since you can't even tell what causes
the error.

So in retrospect:
// no error until a call to writefln,
// which could still potentially not fail => possible bugs
string[2] szFormat = ["%s, %s"];            

// error at runtime, the compiler could have caught this though
static string[2] szFormat2 = ["%s, %s"];
Apr 13 2011
next sibling parent Andrej Mitrovic <none none.none> writes:
Andrej Mitrovic Wrote:

 So in retrospect:
 // no error until a call to writefln,
 // which could still potentially not fail => possible bugs
 string[2] szFormat = ["%s, %s"];            
 
 // error at runtime, the compiler could have caught this though
 static string[2] szFormat2 = ["%s, %s"];
 
Sorry, I've accidentally reversed the two. Fixed: // no error until a call to writefln, // which could still potentially not fail => possible bugs static string[2] szFormat = ["%s, %s"]; // error at runtime, the compiler could have caught this though string[2] szFormat2 = ["%s, %s"];
Apr 13 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 void main()
 {
     static string[2] szFormat = ["%s, %s"];
 }
 
 This compiles, but this is buggy code.
Please vote this old bug report of mine, about this problem: http://d.puremagic.com/issues/show_bug.cgi?id=3849 See also: http://d.puremagic.com/issues/show_bug.cgi?id=481 Bye, bearophile
Apr 13 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Yeah, I don't have a lot of votes left, in fact I only have one left. :s

I think we're basically on our own when it comes to these kinds of
issues. We'll either get a compiler with a better warning system
(maybe GDC.. DDMD in the future), or we'll make some kind of Lint tool
for D. The latter approach might even be better since you could
probably customize such a tool to fit your needs.
Apr 13 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 We'll either get a compiler with a better warning system
In that bug report I ask for an error, not a warning.
 or we'll make some kind of Lint tool for D.
Eventually some lint tools will surely be written for D, but lot of people don't use lints. What I am looking here is a little change in the language. The full proposal has three parts: Refuse array lengths that don't match: int[2] a = [1]; // compile-time error main() {} Introduce [$] to infer the array length at the definition point: int[$] a = [1]; // OK main() {} And introduce a syntax like "..." for the uncommon partial specification situations: int[4] a = [1, 2, ...]; // OK main() {} Bye, bearophile
Apr 13 2011
prev sibling parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 13.04.2011 22:56, Andrej Mitrovic wrote:
 Code:

 void main()
 {
      static string[2] szFormat = ["%s, %s"];
 }

 This compiles, but this is buggy code. The first declaration should have been:
 static string[2] szFormat = ["%s", "%s"];

 I can't tell whether the first case is legit code. You might *want* to
initialize all the elements with the same single initializer. But in that case,
you would write:
 static string[2] szFormat = "%s, ";

 So, without the '[]'.

 If you remove static from the declaration (it's still a static array, I
know!), you'll get a nice runtime error:
 object.Exception src\rt\arraycat.d(31): lengths don't match for array copy

 Actually it's not a nice error message since you can't even tell what causes
the error.

 So in retrospect:
 // no error until a call to writefln,
 // which could still potentially not fail =>  possible bugs
 string[2] szFormat = ["%s, %s"];

 // error at runtime, the compiler could have caught this though
 static string[2] szFormat2 = ["%s, %s"];
Why is this a bug? Static means it's only one instance (per thread), right? The compiler cannot know if you meant to fill the entire array or if you meant something like this static string[2] szFormat = ["%s, %s"]; void main() { szFormat[1] = "%d"; assert(szFormat == ["%s, %s", "%d"]); }
Apr 14 2011
parent bearophile <bearophileHUGS lycos.com> writes:
simendsjo:

 Why is this a bug?
Currently it isn't. But I (and few other people) have asked for it to be a bug, because it sometimes leads to not catching a programmer mistake.
 Static means it's only one instance (per thread), 
 right? The compiler cannot know if you meant to fill the entire array or 
 if you meant something like this
 
 static string[2] szFormat = ["%s, %s"];
 
 void main() {
      szFormat[1] = "%d";
      assert(szFormat == ["%s, %s", "%d"]);
 }
The idea in the proposal on Bugzilla is that a literal like this is a bug: static string[2] szFormat = ["%s, %s"]; If you want to fill some space later there is this syntax that explicitly tells the compiler some items are left undefined (Python Zen rule: explicit is better than implicit): static string[2] szFormat = ["%s, %s", ...]; There is also this syntax to auto determination of the fixed length: static string[$] szFormat = ["%s, %s"]; // length == 1 Bye, bearophile
Apr 14 2011