Re: is there a cleaner way to new a static sized array?

2010-02-25 Thread grauzone

BCS wrote:

I need a function that works like the following:


T* New(T)() { return new T; }


But that also works with static arrays:


auto i = New!(int)();
auto a = New!(int[27])();


The cleanest solution I can think of is:


T* New(T)() { return (new T[1]).ptr; }


but that seems ugly. Any ideas?




Does something like this work as expected?

T* New(T)() { static struct X { T x; } return &(new X).x }

(untested)


Re: exceptions

2010-02-25 Thread grauzone

Ellery Newcomer wrote:

On 02/24/2010 12:37 PM, Robert Clipsham wrote:

On 24/02/10 17:51, Ellery Newcomer wrote:


import tango.core.tools.TraceExceptions;


If you want to use gdb then type 'b _d_throw_exception' (or 'b 
_d_throw'

for dmd) before you run your app. This will break on every exception
thrown, so you may have to hit 'c' a few times to continue at each
thrown exception until you find the one you need.


Thanks!

b _d_throw gives me

Function "_d_throw" not defined.

same for _d_throw_exception.

I can get a breakpoint on _d_arraycopy, but there seem to be way too
many calls for it to be useful.


Hmm, that's odd... if you type b _d_t or b _d_ then you should
get a list of runtime functions, do you see anything listed there that
could be related? It seems odd to me that that function isn't there, it
always is for me. I'm pretty sure I use a debug version of the runtime
though, so that could be it. Your best option is probably to use Tango's
built in stack tracing for now if you can't get gdb working properly.
I've never had issues with it, but I use a custom version of gdb with
the D patches applied, as well as a compiler built with debug symbols,
and the runtime/other libraries built with them too in most cases.


Oooh! nice trick!
Ah, it's '_d_th...@4' and quotes help. Yahoo!


By the way, that's because someone defined _d_throw to have Windows 
calling convention, even on Linux. I wonder what that's useful for.




Do I need to do anything special to get stack tracing to work? when I 
try to compile a simple program it barfs on me and gives


undefined reference to `dladdr'

from

import tango.core.tools.TraceExceptions;


You must link to libdl (-ldl).


void main(){
int[] i = [1,2];
int[]  j = new int[3];
j[] = i[];
}

oh well. Thanks a ton, I'm back in business now!


Re: immutable string literal?

2010-02-22 Thread grauzone

Steven Schveighoffer wrote:

On Mon, 22 Feb 2010 09:27:57 -0500, strtr  wrote:

Thanks, I understand.
But, how about a runtime error?
Isn't a literal placed in easy to identify should-only-read memory?


A segfault is a runtime error.  The problem with Windows is it doesn't 
throw an error on writes to its data segment (unlike Linux).  In 
reality, the result of your program is undefined, so don't expect any 
help from the compiler/runtime.  There's nothing D1 can do about that.  
In order for D to intercept that, it would have to instrument every 
write to memory, and that would cause performance problems like you 
wouldn't believe.


Windows can protect memory as read-only too. Why dmd doesn't do that is 
a mystery. Even if .exe doesn't support read-only data segments, the 
runtime could have done so in early start-up code.



The short answer: Just don't do that.

-Steve


Re: Why isn't == used to compare structs

2010-02-09 Thread grauzone

Don wrote:

Trass3r wrote:
Why isn't == used to compare the struct members in the code above? I 
mean, if I compare the structs with == it could also use == to 
compare the members. If I use "is" to compare the structs it could 
use "is" to compare them members.


Structs are compared *bitwise*!


Not in D2, any more. If a member has an opEquals, it's compared using ==.


Seems arrays inside structs still are not compared with ==.


Re: converting a byte array to a struct array?

2010-01-02 Thread grauzone

Trass3r wrote:

grauzone schrieb:
Second, the bug: casting arrays at compiletime seems to behave 
differently from casting at runtime. Casting at compiletime doesn't 
reinterpret cast, it does conversion! Demonstration here: 
http://codepad.org/OGjXADdu


Feel free to file some bug reports.


Just found out this is stated as a feature in the docs.
http://www.digitalmars.com/d/2.0/expression.html#ArrayLiteral


Interesting. then this is an anti-feature too. At least it sounds like a 
very bad idea. The compiler/language tries to be "smart" here, but only 
introduces inconsistencies.



http://codepad.org/bvk63OPw


Re: What wrong did i do? (key in hashtable is always null)

2009-12-31 Thread grauzone

The Anh Tran wrote:
This is just a small D exercise. I port c++ knucleotide from 
shootout.alioth.debian.org



Issue 1:
If i manually listing hashtable contents, the key does exist in that ht.
But (key in hash_table) always yield null.
Worse, if i use: "auto val = ht[key]", an exception is thrown.

Problem code is from line 163 to 177.


Issue 2:
If I pass an AA (uint[ulong]) to a template function.
DMD complains that uint[ulong] is void.
How can i get the type of AA?

DMD 2.037. Linux Ubuntu.
Source code:
ftp://ftp.4utours.com/dualamd/Dlang/knu5.d


Is your opCmp/toHash really called? Maybe the function signature is off, 
and dmd doesn't "find" the function. Just a guess, I don't really know 
how this D2 stuff works.



Sample data:
ftp://ftp.4utours.com/dualamd/Dlang/fa50k.txt

Thanks.


Re: Memory RAM usage

2009-12-31 Thread grauzone

bearophile wrote:
(I have recently seen a 13X speedup in a not synthetic program just modifying how memory is used and reducing memory usage, keeping the same algorithm. I can show you an URL if you want). 


Yes, please do!


Do you know how can Free Pascal use so little RAM? Here in this nbody benchmark 
(a simple N body gravitational simulation) it seems to use less than half of 
the memory used by C, yet the C code is tight and clean enough, and both use 64 
bit floating point numbers:
http://shootout.alioth.debian.org/u32q/benchmark.php?test=nbody&lang=all&sort=kb
In other benchmarks memory usage of Free Pascal is not dramatically lower, but 
it's usually near the top of lower memory usage in all Shootout benchmarks.


No idea. I just know that FPC doesn't use GCC. I think it doesn't even 
link to libc! (I can't really confirm, ldd crashes on the executable 
produced by fpc.) Maybe it just avoids some constant overhead due to this.



Bye,
bearophile


Re: define new types within templates

2009-12-30 Thread grauzone

teo wrote:
There was a way to define new types within templates and I think that I 
have seen that demonstrated here in the newsgroups, but cannot find it 
now. Can someone help me please?


I would like to do something like this:

template MyTemplate(T)
{
  struct T ~ "Struct"  // define FooStruct structure
  {
int x;
  }
  class T ~ "Class"  // define FooClass class
  {
void bar(T ~ "Struct" t)
{
  // ...
}
  }
}

void main()
{
  mixin MyTemplate!("Foo");
  FooStruct t;
  FooClass f = new FooClass();
  f.bar(t);
}

Hopefully I am not mistaken.


I don't know for what you're asking, but there's absolutely no need to 
use string mixins (see Trass3r's reply).


Instead you can just define a type inside the template, and then access 
it by instantiating it:


template MyTemplate(T) {
   struct Struct {
 T x;
   }
}

void main() {
   MyTemplate!(int).Struct t;
   t.x = 123;
}

You can use mixin MyTemplate!(int); to bring "Struct" into the module 
namespace, and you can use e.g. "alias MyTemplate!(int) IntStruct;" to 
save typing.


Re: converting a byte array to a struct array?

2009-12-30 Thread grauzone

Trass3r wrote:
I got some RGB palette in a byte array which I'd like to convert or 
"map" to an RGB struct array, isn't this easily possible without using 
dozens of struct constructors?



RGB[256] PALETTE = cast(RGB[256]) [
0x00, 0x00, 0x00, 0xE3, 0x53, 0x00,
0xCF, 0x4B, 0x07, 0xBF, 0x43, 0x0F, ...

doesn't work cause of "non-constant expression"

RGB[256] PALETTE = (cast(RGB[]) [
0x00, 0x00, 0x00, 0xE3, 0x53, 0x00,
0xCF, 0x4B, 0x07, 0xBF, 0x43, 0x0F, ...
]) (0 .. 256);

compiles, but yields empty structs (and doesn't seem right anyway).


You've hit both an anti-feature and a bug.

First the anti-feature: [0xAB, ...] will yield an int[], not a ubyte[] 
(I guess ubyte[] is what you're expecting). If you cast two arrays, the 
compiler will reinterpret cast all data. The result won't be what you 
intended.


Second, the bug: casting arrays at compiletime seems to behave 
differently from casting at runtime. Casting at compiletime doesn't 
reinterpret cast, it does conversion! Demonstration here: 
http://codepad.org/OGjXADdu


Feel free to file some bug reports.


Re: floating point verification using is?

2009-12-18 Thread grauzone

bearophile wrote:

Steven Schveighoffer:

If I have 2 identical floating point values, how do I ensure they are  
binary equivalents of eachother?


Try this inside std.math of Phobos2:
bool isIdentical(real x, real y);


I thought 'a is b' would work, but it just morphs into a == b, which isn't  
helpful.  Why doesn't 'is' just do a bit compare for floating points?


"is" is used to compare references.


No. If you use it with structs, the type's opEquals is not called. "is" 
is used for a lot of things.


I agree that is should do a bitwise comparison for floating points. That 
would be a nice fix for D2.



Bye,
bearophile


Re: Immutable & circular imports

2009-12-16 Thread grauzone

Tomek Sowiński wrote:
Amusing things happen when immutable arguments and circular imports are 
put together:


--
module hello;
import test;

struct Strukt {
Staly* s;
}
--
module test;
import hello;

immutable struct Staly {
int a;
}

void f_strukt(Strukt* stk) {
f_staly(stk.s);// ups!
}

void f_staly(Staly* s) { }
--

Error: function test.f_staly (immutable(Staly)* s) is not callable using 
argument types (Staly*)
Error: cannot implicitly convert expression ((*stk).s) of type Staly* to 
immutable(Staly)*


Am I writing code too weird or is this a compiler bug? The only thing 
about circular imports on D page is: "Cycles (circular dependencies) in 
the import declarations are allowed as long as not both of the modules 
contain static constructors or static destructors." So what I tried to 
pull off seems fair game.


There are a _lot_ of circular dependency bugs, and there are a lot of 
immutable related bugs. Combine both together and you get... probably 
even more bugs.




Tomek


Re: Tempated class instantiation

2009-12-16 Thread grauzone

Mike L. wrote:

I'm making a class template that only works with strings, so I thought it'd be 
good to instantiate each template with char, wchar, and dchar right in the 
template's module so that when it's compiled it'll be part of the .obj file and 
won't have to compile it for every other project that uses it. However, I get 
an error reproducible with this:

module test;

class A(T)
{
version(broken)
{
class B
{
T blah() { return t; }
}
}

T t;
}

mixin A!(int);

int main()
{
A!(int) a = new A!(int)();
return 0;
}

If what I want to do makes sense, how should I be doing it?


AFAIK it works if you do

alias B!(int) Something;

If you want to get the above code to work, use template A(T) instead of 
class A(T) + mixin.


Re: Compilation constants

2009-11-11 Thread grauzone

Phil Deets wrote:

On Wed, 11 Nov 2009 13:34:32 -0500, Phil Deets  wrote:

On Wed, 11 Nov 2009 13:30:17 -0500, Phil Deets  
wrote:


On Wed, 11 Nov 2009 08:50:48 -0500, bearophile 
 wrote:


In a C program I have a numeric constant SIZE (that is in [1,32]), 
that I can define when I compile the code, like this:

gcc -DSIZE=14 ...

How can I do the same thing in D? The solution I have found is to 
put in the D code:

version(B1) const SIZE = 1;
version(B2) const SIZE = 2;
version(B3) const SIZE = 3;
version(B4) const SIZE = 4;
...
version(B14) const SIZE = 14;
...

And then compile the D program with:
dmd -version=B14 ...
Or:
ldc -d-version=B14 ...

Do you know nicer ways to do this in D? (if there are no nicer ways, 
is this simple feature worth adding to D?)


Thank you, bye,
bearophile


What I would probably do is generate a simple .d file right before 
you compile.


I'm used to using forums where I can post, look at what I wrote, then 
edit if necessary. To continue my thought, the file could be called 
constants.d and it could contain just be just one line:


enum SIZE=14;


Or use import expressions and mixins, something like 
mixin("SIZE="~import("config.txt"));


But actually, that's horrible.


See, I need edit functionality :). s/just be just/just/


You can delete your posts to emulate editing...


Re: FMOD working with Windows

2009-11-10 Thread grauzone

Joel Christensen wrote:

grauzone wrote:

Joel Christensen wrote:
FMOD sound (record and play) is off D Programming web site. 
http://wiki.dprogramming.com/FMod/HomePage


I followed instructions from the web site. But one instruction said 
to use 'coffimplib.exe' but I couldn't see where it is to download 
it, and one link wasn't found (Dr.Dobb).


You can avoid the whole crap with linking to a .lib and use derelict.
Derelict simply dynamically loads the DLL.


I've already tried derelict. I don't know how to use it to either record 
or even play audio files.


1. Get the derelict fmod bindings (I think they are not in the derelict 
svn, but there's a link on the derelict project page on dsource)

2. import derelict.fmod.fmod;
3. DerelictFMOD.load();
4. Use the fmod API normally

I have in the past gotten FMOD working (record and play I think, record 
at lessed) with C++. Using the tools 'copy' and 'paste'.


Also there's a library I use that has recording ability, but I don't how 
to use it either.


Re: FMOD working with Windows

2009-11-09 Thread grauzone

Joel Christensen wrote:
FMOD sound (record and play) is off D Programming web site. 
http://wiki.dprogramming.com/FMod/HomePage


I followed instructions from the web site. But one instruction said to 
use 'coffimplib.exe' but I couldn't see where it is to download it, and 
one link wasn't found (Dr.Dobb).


You can avoid the whole crap with linking to a .lib and use derelict.
Derelict simply dynamically loads the DLL.


Re: How to run unittests?

2009-10-31 Thread grauzone

al wrote:

It seems that unittests are not run (I've tried putting while(1){} and writef() 
there - no effect).

Even this code doesn't run assert():

import std.stdio;

int main(string[] args)
{
assert(args.length == -1);
writef("shouldn't work!");
return 0;
}


I'm using:

dmd -debug -w -unittest -run main.d

Is there a secred debug switch, or is it simply a bug? Which version of DMD is 
usable? (I've got v1.050)



I think it's a bug. Works for me under Linux. I guess the OSX versions 
of dmd are simply not in a useable state yet.


Re: How to override function?

2009-10-22 Thread grauzone

Zarathustra wrote:

I would like to know, how to override function if subclass and super class are 
located in the same package and different modules.

For instance when they are in the same module:
//___
module main;
class Foo{

  this(){
proc();
  }
  
  void proc(){

writefln("Foo");
  }
}

class Bar : Foo{
  override void proc(){
writefln("Bar");
  }
}

void main(){
  new Bar;
}
//___
the result is "Bar" so it's great, but:

//___
module pack.foo;

class Foo{

  this(){
proc();
  }
  
  package void proc(){ // without 'package' it works well

writefln("Foo");
  }
}

//___
module pack.bar;

class Bar : Foo{
  package override void proc(){ // without 'package' it works well
writefln("Bar");
  }
}
//___
module main;
void main(){
  new Bar;
}
//___
the result is "Foo" so it's unexpected to me.


It's a bug. package functions are never virtual, and the "override" 
attribute is just ignored. Same with private. Welcome to D.


Re: Sorry, I just love templates, AAs and mixins :)

2009-10-17 Thread grauzone

Saaa wrote:

public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
{
  mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
  if( elements == null )
  {
ET[] temp;
temp.length = 1;
temp[0] = element;
mixin(var_name~`[key] = temp;`);
  }
  else
  {
(*elements).length = (*elements).length + 1;
(*elements)[(*elements).length-1] = element;
  }
} 





It's unreadable. What the hell does it do? How do you use it?
It's a good example how you can write-only code in D.


Re: Sizeof class instance

2009-10-04 Thread grauzone

Justin Johansson wrote:

grauzone Wrote:


Justin Johansson wrote:

How does one determine the sizeof (in bytes) of an instance of a class in D?

.sizeof works as advertised for structs, but for reference types,
.sizeof yields the sizeof the referencing variable (effectively same as size of 
a pointer)
and not the size of the underlying instance.

As Jarrett said, x.classinfo.init.length is the simplest way in D1.


I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the 
latter.
I guess that PDF is horribly outdated, although it may work for some 
purposes.



btw. I was poking under the hood of std.xml and though, wow, instances of 
Element
class look humongous, and so I'm interested to how exactly how humongous.
Wasn't std.xml for D2? Anyway, last what I remember is that std.xml is 
unmaintained, slow, buggy, and shouldn't be seriously used.


Yes and yes.  I'm currently using D1 but with view to D2 am having a peek at 
it's libs.

I can see why std.xml in D2 is slow, and would not be surprised if buggy as 
well;  it is quite disgusting code that's been hacked together without any real 
rhyme or reason.  So guess I'll be writing my own stuff
and leveraging on C libs where possible.  Got Expat parser running with D 
without too much trouble.


In case you didn't know, Tango's XML parser is said to be even faster 
than other commonly used XML parsers in C/Java: 
http://dotnot.org/blog/archives/2008/03/10/xml-benchmarks-updated-graphs-with-rapidxml/


Also: http://prowiki.org/wiki4d/wiki.cgi?AllLibraries/XmlLibraries


Thanks for comment grauzone.

-- Justin Johansson
 


Re: Sizeof class instance

2009-10-04 Thread grauzone

Justin Johansson wrote:

How does one determine the sizeof (in bytes) of an instance of a class in D?

.sizeof works as advertised for structs, but for reference types,
.sizeof yields the sizeof the referencing variable (effectively same as size of 
a pointer)
and not the size of the underlying instance.


As Jarrett said, x.classinfo.init.length is the simplest way in D1.


I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in the 
latter.


I guess that PDF is horribly outdated, although it may work for some 
purposes.



btw. I was poking under the hood of std.xml and though, wow, instances of 
Element
class look humongous, and so I'm interested to how exactly how humongous.


Wasn't std.xml for D2? Anyway, last what I remember is that std.xml is 
unmaintained, slow, buggy, and shouldn't be seriously used.



Thanks for all help.
Justin



Re: Linking in an .so on linux with rebuild?

2009-09-22 Thread grauzone

Daniel Keep wrote:

I found a solution.

See
http://stackoverflow.com/questions/335928/linux-gcc-linking-ld-cannot-find-a-library-that-exists

For me, I needed readline and history, so I did this:

$ cd /lib
$ sudo ln -s libreadline.so.5 libreadline.so
$ sudo ln -s libhistory.so.5 libhistory.so

After that, ld didn't complain.


Interesting. On my system (Debian), the libreadline.so symlink is in a 
separate -dev package. Who knows why.


Re: Linking in an .so on linux with rebuild?

2009-09-22 Thread grauzone

Nick Sabalausky wrote:
I can't seem to get that to work. Tried all sorts of stuff. Off the top of 
my head:


-ll


This should work. If the lib is named "libsomething", don't include the 
"lib": -llsomething


Excluding the "lib" seems to be standard on Unix-like OSes.


-ll.so
"-L-l "
"-L-l .so"
-L-l -L
-L-l -L.so

None of them were able to find the file (and, yes, the name+path are right), 
and I'm not using any links.





Re: D1: std.md5: corrections for the given example

2009-09-19 Thread grauzone

notna wrote:

grauzone schrieb:


md5_example_2.d(7): expression expected, not 'auto'
md5_example_2.d(7): found 'len' when expecting ')'
md5_example_2.d(7): found '=' instead of statement

(this is line 7 after I removed comments and blank lines from your 
edit)


Stewart.


God I'm stupid.

Sorry.

I guess I wish that worked.


http://d.puremagic.com/issues/enter_bug.cgi


???

What do you wanna tell us? That
  while (auto len = file.readBlock(buffer.ptr, buffer.sizeof))
has to work and does not because it's a bug? And that's why you think a 
bug report should be opened?


Enhancement request to allow auto in while, to make it consistent with 
if. (You can write "if(auto x = foo()) {...}")


Re: D1: std.md5: corrections for the given example

2009-09-18 Thread grauzone

downs wrote:

Stewart Gordon wrote:

downs wrote:


while (auto len = file.readBlock(buffer.ptr, buffer.sizeof))



md5_example_2.d(7): expression expected, not 'auto'
md5_example_2.d(7): found 'len' when expecting ')'
md5_example_2.d(7): found '=' instead of statement

(this is line 7 after I removed comments and blank lines from your edit)

Stewart.


God I'm stupid.

Sorry.

I guess I wish that worked.


http://d.puremagic.com/issues/enter_bug.cgi


Re: How does D cope with aliasing

2009-09-09 Thread grauzone

#ponce wrote:

Stewart Gordon Wrote:
My recollection of reading the spec is that a D compiler is allowed to 
optimise by assuming no pointer aliasing.  But I can't remember at the 
moment where I read this.


I don't know if this is neat or nasty for a compiler to do so. 


OT : Is there a DMD switch to disable bound check exceptions ? This way I 
wouldn't have to rely on pointers so much.


If you always want DMD never to bounds check for specific code, you just 
can write "a.ptr[index]" instead of "a[index]" (when a is an array). 
That's because array.ptr returns a pointer to the first element, and 
using [] on a pointer works exactly like C pointer math. The good thing 
about this is that you still can use array slices and the .length field, 
so the code most likely is less messy than the C version would be.


Re: Any way to workaround Optlink crash?

2009-09-02 Thread grauzone

div0 wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Jérôme M. Berger wrote:

Max Samukha wrote:

Tom S wrote:

Max Samukha wrote:
COFF/ELF output would not be that bad though, at least if there's some
linker that supports these *and* its license allows it to be bundled
with DMD.

I doubt such a linker exists. And if it does, I doubt it is of quality
good enough to replace OPTLINK.


GNU ld supports these formats on *nix, windows and MacOS. It has
very good quality and its license allows it to be bundled with anything...

Jerome


Yeah but have you actually linked a D program with it? (esp. on 'doze)


Probably that wasn't really clear: dmd on Linux uses GNU ld for linking. 
Walter has an ELF backend for this. Walter also wrote a backend for Mach 
for the MacOSX port.



- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFKnZkuT9LetA9XoXwRAv5BAJ4+P/lRQsHCVN/eDrZaAgPvHsbWZACdF/Dx
7CQ28E5zAM4v2aNWM9RCMms=
=kOpB
-END PGP SIGNATURE-


Re: Error: constant false is not an lvalue

2009-08-30 Thread grauzone

I wouldn't be surprised if W himself has forgotten about this rule,
since other parts of the spec make no mention of it, or seem to depend
on the default-initialization of variables.

"If the Initializer is void, however, the variable is not initialized.
If its value is used before it is set, undefined program behavior will
result."
http://www.digitalmars.com/d/1.0/declaration.html


And below that, there's even an example with local variables.

I think what you were referring to is an outdated part of the 
specification, especially because "= void;" was added only recently.


(Which also shows how worthless the specification is: not only 
incomplete, but full or inconsistencies and errors?)


As to whether initializing variables by default or disallowing reading 
uninitialized values is better: I think it's very annoying, if the 
compiler tries to be smart, but then comes in to your way. Additionally, 
the result of the uninitialized value detection might end up being 
compiler specific, and that wouldn't be beautiful at all anymore. 
Actually, that case is very likely, since Walter would never rigorously 
define how exactly it should be done.


Re: Error: constant false is not an lvalue

2009-08-30 Thread grauzone

Jarrett Billingsley wrote:

On Sun, Aug 30, 2009 at 12:24 AM, Ary Borenszweig wrote:

Steven Schveighoffer escribió:

On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer
 wrote:


void blah(out bool a = false){
 // blah blah blah
}

compile time use of blah results in error.

Am I doing anything wrong?

out implies a reference.  You can't have a reference to a manifest
constant like that.

If you want to ensure a is false at the beginning of the function do:

void blah(out bool a)
{
 a = false;
 // blah blah blah
}

-Steve

Or just not write it, because "out" automatically initializes the value of
the variable to it's default one, in the case of bool it's false.


Although teeechnically speaking that would be illegal code. The D
spec says that it's not legal to use the value of uninitialized
variables. Default initialization is kind of a poor man's substitute
for actual flow control which determines that. By relying on default


Am I the only one, who likes the current behaviour, and finds it 
annoying to be forced by the compiler to initialize all variables?



initialization, you're relying on what is actually nonconformant
behavior, and it could be broken in the future or by a smarter
compiler.


How is this nonconformant? Initialization is guaranteed by D.


But we're getting really technical here ;)


Re: Strange calculation problem

2009-08-25 Thread grauzone

bearophile wrote:

Lars T. Kyllingstad:
I think the compiler should be smart enough to figure this out for 
itself, but until that happens you can work around it by suffixing at 
least one of the integer literals with LU, so the compiler interprets 
the entire expression as an ulong:


To make this fix happen Walter has to know this problem exists...


And this is why bug reports were invented...


Bye,
bearophile


Re: CRTP in D?

2009-08-19 Thread grauzone

bearophile wrote:

I don't know much C++. Can CRTP be used in D1 too, to improve the performance 
of some D1 code?

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern


Why don't you just go and try?
If you hit forward referencing errors when using structs, try classes 
with final methods.



Bye,
bearophile


Re: 'static' keyword for positional array initialization

2009-08-12 Thread grauzone

Ali Cehreli wrote:

Lars T. Kyllingstad Wrote:

I've tried with DMD 2.031, and I can't reproduce this. This works fine 
for me:


   int[2] static_0 = [ 1, 1 ]:
   int[2] static_1 = [ 1:1 ];

Where did you put the declarations? I've tried putting them at both 
module level and in a class, and both times it compiled without problems.


Thank you very much for both of your answers. :)

I hadn't realized that the location of the definitions would make a difference. 
As you say, both of the lines work for me in the global scope (probably in a 
class too), but not in main:

void main()
{
int[2] static_0 = [ 1, 1 ];
int[2] static_1 = [ 1:1 ];
}

dmd: init.c:431: virtual Expression* ArrayInitializer::toExpression(): Assertion 
`j < edim' failed.

The 'static' keyword on the 1:1 line fixes the problem...


The error message is a compiler bug, but AFAIK the code above is not 
valid anyway. The special initializer syntax (apparently called static 
inittializers) for arrays and structs only works for data that's stored 
on the data segment. This applies for global variables, static 
variables, and class member initializers.


It simply doesn't work for normal variables, which allocate their 
storage on the stack.


Re: Pointer to method C++ style

2009-07-24 Thread grauzone

 LOOKUP_TABLE[0] = Method("method1", &Component.method1);
 LOOKUP_TABLE[1] = Method("method2", &Component.method2);


These two lines are weird.  ``pragma(msg)`` shows that type of
``&method1`` is ``void function()`` while it must be ``void delegate()``
for a non-static member because of difference in calling convention.
Actually I think that taking an address of a non-static member in a
static context must be a compile time error.


It's because I'm taking the address of the function on the type, not on 
an instance.  It's not a delegate because there's no "this" pointer yet.


It makes sense to me anyways.  A delegate is a normal function pointer 
coupled with a hidden context parameter.


But you can't call that function pointer. Actually, you can probably 
subvert type safety, because functions have a different calling 
conventions from delegates. This also means that SafeD should disallow 
taking the address of methods from a type (without instance).


That's really silly. A nicer way would be to make &Type.method return a 
delegate with ptr set to null. Then calling this delegate would result 
in a (harmless) null pointer exception.


But even then, there's no safe way to construct a real delegate out of 
the method pointer. You can't simply assign an object instance to ptr, 
because you can't statically know if the funcptr of the delegate really 
is a method of that object instance.


Looks like SafeD proves to be unfeasible again.


Re: dmd crashes with "out of memory" error

2009-07-15 Thread grauzone

Trass3r wrote:

Robert Fraser schrieb:
File is probably too big. Remember that for every byte in your binary, 
DMD is likely allocating several hundred for the literal xpression 
object + codegen for the expression, etc., and frees very little 
dynamically allocated memory.




So we can't even embed a 1.7 MB file?


For embedding data, use import() 
(http://www.digitalmars.com/d/1.0/expression.html#ImportExpression).
Or did you do this? I don't know the file size restrictions of import 
either.


Re: Array slice length confusion

2009-07-09 Thread grauzone

Daniel Keep wrote:


Tim Matthews wrote:

Kagamin wrote:

Tim Matthews Wrote:


I thought a slice would behave slighty different due to some sort of
meta data that is a separate area of memory so it doesn't effect D's
abi.


Current plan is to introduce new type - array - into the language.

Do you know the ng posts or where ever that was posted?


Best bet would be to search for "T[new]".


Superseded by Andrei's Array struct.


Re: Should be easy

2009-06-12 Thread grauzone

Ever heard of recursion?

Why don't you simply handle all types recursively? Why do you need this 
"array depth" stuff?


Re: Inside the switch statement

2009-06-09 Thread grauzone

BCS wrote:

Hello grauzone,


http://groups.google.com/group/net.lang.c/msg/66008138e07aa94c


Many people (even Brian Kernighan?) have said that the worst feature
of C is that switches don't break automatically before each case
label.

Oh god, that's from 1984, and even today we're struggling with this
bullshit in the most modern dialect of C, D.



I'm sorry, you don't have my sympathy on this one. There are to many 
place I've used fall throught to chuck it out.


What kind of fall-throughs were these?

A:

case value1:
case value2:
case valueN:
code1();
break;

B:

case value1:
code1();
case value2:
code2();
break;


Re: Inside the switch statement

2009-06-09 Thread grauzone

http://groups.google.com/group/net.lang.c/msg/66008138e07aa94c


>Many people (even Brian Kernighan?) have said that the worst feature 
of C is that switches don't break automatically before each case label.


Oh god, that's from 1984, and even today we're struggling with this 
bullshit in the most modern dialect of C, D.


Re: legal identifier check

2009-05-31 Thread grauzone

Saaa wrote:

Hello Saaa,


static if(is(typeof({ /* code to be checked for validity goes here */
}))) ...


How does that piece of code work anyways :D


that checks to see if the {...} is a valid delegate literal by using is() 
to see if semantic checks fail.


Ah, I see. Can this be done at runtime? 



You have to write it yourself. Here's a good starting point:
http://www.digitalmars.com/d/1.0/lex.html#identifier


Re: Encoding problems...

2009-05-28 Thread grauzone
Robert Fraser wrote:
> Jarrett Billingsley wrote:
>> On Wed, May 27, 2009 at 8:55 PM, Robert Fraser
>>  wrote:
>>> Hi all,
>>>
>>> Quick question: I want to use some unicode identifiers, but I get
>>> "unsupported char 0xe2", both with using and not using a BOM. The characters
>>> in question are the superset/subset-equals operators: ⊇ and ⊆... Perhaps
>>> these are just unsupported by DMD (in which case, I'll file a bug)?
>>>
>>> Thanks,
>>> Robert
>> If they're not classified as "universal alpha" I don't think you can
>> use them in identifiers.

How the hell did your news client switch from UTF-8 to
Japanese-something? (charset=UTF-8 => charset=ISO-2022-JP)

> 
> Lame. K; thanks.

Don't worry, people working with your code will be thankful!


Re: synchronized and thread

2009-05-18 Thread grauzone

reimi gibbons wrote:

if i encapsulate a part of statements within function with synchronized keyword 
and then let says 1 thread is calling the function, then another thread try to 
access it, will d put the later thread to wait (sleep) until the 1st call 
finished it or it will signal failure to access? thanks


The other thread will wait.


Re: Comparing D structs

2009-05-17 Thread grauzone

Dan wrote:

That sounds great, and seems like yet another reason for me to switch to D 
(other than the removal of header files which always seemed like a kludge).


I heard that the compiler can change the padding bytes to non-null on 
some occasions. For example, the compiler could treat member a as 32 bit 
value when assigning it:


struct {
   char a; //offset 0
   int b;  //offset 4
}

Nothing in the C standard says that the compiler has to preserve the 
padding bytes between a and b. So I was told.



Just for the record though, I think one can initialize/blank/calloc C structs 
too, but the problem is that some struct elements (of the same array) may have 
padding while others don't, or perhaps they have different size paddings.


Not sure what you mean.


Re: Comparing D structs

2009-05-17 Thread grauzone

Dan wrote:

Structs can't easily be compared in C because of potential 'padding' inside the 
struct which may (or may not) exist.

I was jut wondering if D somehow gets round this, and allows something like 
memcmp to easily compare two structs.


How about using the == operator?


Re: Who wants to have some fun memory debugging?

2009-05-12 Thread grauzone

Maybe it's time to put together an instrumented GC...


Wishlist:
- some way to know _when_ a collection happened (or how often)
- logging of allocations (module/linenumber of allocator, size of 
allocation, type of allocation)

- per TypeInfo allocation statistics
- per module allocation statistics


Re: Who wants to have some fun memory debugging?

2009-05-12 Thread grauzone
Wild guess: there's a false pointer, that keeps one element in the list 
from being collected, and because the list-prev pointers are still 
there, all following elements won't be collected either in consequence.


If I had time, I'd try two experiments:
1. before freeing everything, reset the prev field of each element; if 
this makes the leak go away, my guess would probably be right
2. use the destructor (Data had to be a class) to keep track of how many 
elements are actually freed by the GC (just a thread safe counter, 
that's incremented in the ctor and decremented in the dtor); just to 
find out if this is an internal GC problem, or if you have too many live 
garbage


Re: 3 variant questions

2009-05-12 Thread grauzone
Dear Saaa, these varargs suck badly and you shouldn't use them. It's so 
simple to introduce portability errors or heisenbugs, and it's 
incredibly hard to get it right. You're better off with alternatives.


Alternative 1: Typesafe Variadic Functions
Useful if the variadic arguments should have only one type. And they're 
very easy to use. It's documented somewhere on 
http://www.digitalmars.com/d/1.0/function.html


Alternative 2: Tuples
http://www.digitalmars.com/d/1.0/template.html#TemplateTupleParameter
The variadic arguments can have any types, but such functions can't 
really be virtual methods or delegates.



Why is this extra step necessary and why won't simple casting not work?


You should never directly work with _argptr.  It's not guaranteed to be
a simple pointer.  For example, I believe that GCC will sometimes use
registers (God only knows WHY).


I think it's because GCC tries to keep the usual calling convention, 
where some arguments are passed as registers. Which is utterly pointless 
and stupid (ok, maybe it was easier to implement in gdc), and turns 
using varargs into hell.


It would be so simple if _argptr was just an array of pointers to the 
actual arguments. It'd be so simple it makes me mad.


Re: D input: how-to (RFC)

2009-05-11 Thread grauzone

int read(/+File inFile = stdin,+/ A...)(out A a) /+Uncommenting results
in: Error: arithmetic/string type expected for value-parameter, not
File+/


That would make inFile a template parameter, which obviously doesn't
make sense with objects, and I guess File is an object. This should work:

int read(A...)(File inFile, out A a)


OK... that works, but how would I set stdin as the default input "file"?


You can't have default arguments and variadic arguments at the same 
time. That's just how the syntax works. At best, you could change the 
signature to "int read(A...)(ref A a)". Then you could check if the 
first argument is of the type File, and if not, use a default value for 
inFile, and so on.


I tried: int read(A...)(out A a, File inFile = stdin) but the compiler 
hangs trying to compile it whenever I call read() using 50% of the CPU 
resource in the process.


No matter if it's allowed or not, the compiler shouldn't hang. Maybe 
report a bug: http://d.puremagic.com/issues/



bools can't be read? If the implementation is incomplete, there should
be at least an "assert(false);", maybe even a "static assert(false);".


Got it. What value would you read for a bool though? to me it can be 
0||1, true||false, yes||no, etc... Would I simply use 0 && 1 and forget 
about the rest?


Because this function seems to deal with user input, maybe you should 
allow as many as possible.



else static if(is(typeof(t) == string))
if(a.length > 1)
a[i] = input[i];
else
a[i] = data;



Also, the array index i isn't checked for input, and random things could
happen. (You'd get an exception in debug mode, but not in release mode.)


??? not sure what you mean here. i is the index of the variable as it 
appears in the tuple "A". Why would I need to check it for input? i is 
valid as long as we have not reached the end of the tuple.


You loop over a, so a[i] will always be correct. But input[i] could be 
out of bounds, as far as I can see.



Shouldn't split() already remove all white space?


split removes the white space but only from the copy of the string 
returned. The original remains untouched.


Oops... right.


Re: D input: how-to (RFC)

2009-05-10 Thread grauzone

Tyro[a.c.edwards] wrote:
I am looking for a D version of scanf() but I'm sure there is no such 
thing so I tried contrived one. I am sure I missed a slew of obvious 


There's readf() in std.stream. I think you have to use std.cstream : din 
to use it with stdin.



int read(/+File inFile = stdin,+/ A...)(out A a) /+Uncommenting results
in: Error: arithmetic/string type expected for value-parameter, not
File+/


That would make inFile a template parameter, which obviously doesn't 
make sense with objects, and I guess File is an object. This should work:


int read(A...)(File inFile, out A a)


{  start:
   auto data = stripr(readln());
   auto input = split(data);

   string assign()
   {
   return
   `  try {
  if(a.length != input.length)
  return -1;
  a[i] = to!(typeof(t))(input[i]);
  } catch (ConvError e) {
writeln("Invalid input!");
goto start;
  }`;
   }


If the user types in too much or too less input, read() returns with an 
error (-1), and the caller has to deal with it.
If the user typed in something unparseable, the function prompts an 
error and lets the user retry.

This is inconsistent.

Also, instead of using CTFE to return a const string, why not simply

const assign = `  ` ;

You're using D 2.0, you probably have to replace "const" by "enum". I 
don't know.


You use goto to retry. I'd replace it by a loop. If someone wants to 
argue with me if goto is or is not evil, go ahead.



   foreach(i, t; a)
   {
 static if(is(typeof(t) == void))
   {}
 else static if(is(typeof(t) == bool))
   {}


bools can't be read? If the implementation is incomplete, there should 
be at least an "assert(false);", maybe even a "static assert(false);".



 else static if(is(typeof(t) == byte))
   mixin(assign);
 else static if(is(typeof(t) == ubyte))
   mixin(assign);
 else static if(is(typeof(t) == short))
   mixin(assign);
 else static if(is(typeof(t) == ushort))
   mixin(assign);
 else static if(is(typeof(t) == int))
   mixin(assign);
 else static if(is(typeof(t) == uint))
   mixin(assign);
 else static if(is(typeof(t) == long))
   mixin(assign);
 else static if(is(typeof(t) == ulong))
   mixin(assign);
 /+static if(is(typeof(t) == cent))
   mixin(assign);
 static if(is(typeof(t) == ucent))
   mixin(assign);+/
 else static if(is(typeof(t) == float))
   mixin(assign);
 else static if(is(typeof(t) == double))
   mixin(assign);
 else static if(is(typeof(t) == real))
   mixin(assign);


Oh god, what the fuck! String mixins are the new #define! OK, at least 
this reduces the code duplication, but the code duplication shouldn't be 
there in the first place.


You could just throw all the types into a tuple, and then foreach() on 
it, checking for the type in each iteration.


Or just make a single giant if() statement to check for all types to!() 
supports (like if(is(typeof(t) == int) && is(typeof(t) == uint)...). In 
any case, you could reduce the number of is() parts by using isNumeric() 
from std.traits.


Or find a way to check for to!() supported data types automatically (but 
I don't know to!() well enough if this is possible).



 else static if(is(typeof(t) == ifloat))
   a[i] = ifloat.max;
 else static if(is(typeof(t) == idouble))
   a[i] = idouble.max;
 else static if(is(typeof(t) == ireal))
   a[i] = ireal.max;
 else static if(is(typeof(t) == cfloat))
   a[i] = cfloat.max;
 else static if(is(typeof(t) == cdouble))
   a[i] = cdouble.max;
 else static if(is(typeof(t) == creal))
   a[i] = creal.max;


What?


 else static if(is(typeof(t) == char))
   a[i] = input[i][0];


input could be an empty string, and random things could happen.


 else static if(is(typeof(t) == wchar))
   mixin(assign);
 else static if(is(typeof(t) == dchar))
   a[i] = input[i][0];
 else static if(is(typeof(t) == string))
   if(a.length > 1)
 a[i] = input[i];
   else
 a[i] = data;


I see, if the caller of the function only requests a char[], the 
splitting by white space is disregarded, and the whole string is 
returned. Isn't that a but inconsistent? At least, it could always 
return the remainder of the string, if this char[] parameter is the last 
of the function.


Also, the array index i isn't checked for input, and random things could 
happen. (You'd get an exception in debug mode, but not in release mode.)


Also, http://en.wikipedia.org/wiki/Dangling_else


 else static if(is(typeof(t) == dstring))
   {}
 else static if(is(typeof(t) == char[]))
   a[i] = stripr(data).dup;


Shouldn't split() already remove all white space?


   }
   return 0;
}


Re: dmd on ubuntu installation

2009-05-10 Thread grauzone

Michael P. wrote:

Michael P. Wrote:


Mike Parker Wrote:


Michael P. wrote:

Frits van Bommel Wrote:


Michael P. wrote:

But when I type dmd in the terminal, I get this:

mich...@ubuntu:~$ dmd
bash: /usr/local/bin/dmd: Permission denied
mich...@ubuntu:~$ 


Do you know why?

Looks like you didn't "chmod +x" it. Zip files don't store *nix permissions...

Okay, but what should I do to fix that? I tried:
mich...@ubuntu:~$ chmod u+x /usr/local/bin/{dmd,dumpobj,obj2asm,rdmd}
chmod: changing permissions of `/usr/local/bin/dmd': Operation not permitted
chmod: changing permissions of `/usr/local/bin/dumpobj': Operation not permitted
chmod: changing permissions of `/usr/local/bin/obj2asm': Operation not permitted
chmod: changing permissions of `/usr/local/bin/rdmd': Operation not permitted
mich...@ubuntu:~$ 
but that happened. :(



Try adding 'sudo' to the front of the chmod command line. You have to 
execute it as root.

Okay, I still can't run dmd. I get the same thing. But it works when I do sudo 
dmd.

mich...@ubuntu:~/d$ cd ..
mich...@ubuntu:~$ sudo chmod u+x /usr/local/bin/{dmd,dumpobj,obj2asm,rdmd}
[sudo] password for michael: 
mich...@ubuntu:~$ dmd

bash: /usr/local/bin/dmd: Permission denied
mich...@ubuntu:~$ sudo dmd
Digital Mars D Compiler v1.043
Copyright (c) 1999-2009 by Digital Mars written by Walter Bright
Documentation: http://www.digitalmars.com/d/1.0/index.html
Usage:
*snip*
mich...@ubuntu:~$ dmd
bash: /usr/local/bin/dmd: Permission denied
mich...@ubuntu:~$ 


Any suggestions now?

BTW, I did get a .d file to compile. Had to use 'sudo dmd' and not just 'dmd'.


The files are probably not readable (r) or executable (x) by all other 
users (o). Try "chmod o+rx /usr/local/bin/dmd".


Re: Resource availability: fonts

2009-05-06 Thread grauzone

http://digitalmars.com/d/1.0/expression.html#ImportExpression

It returns a char[], which is a misdesign, because the loaded file can 
be binary data as well. I think.


Re: Resource availability: fonts

2009-05-05 Thread grauzone

Use
ubyte[] fontbytes = cast(ubyte[])import("yourfont.ttf");


Re: Get the name of a function and the parameters?

2009-04-29 Thread grauzone
D". Because a D compiler that doesn't use DMD's front-end is not D 
compatible. Because the front end *is* the specification of the language.


...and it's full of bugs.


Re: Get the name of a function and the parameters?

2009-04-29 Thread grauzone

Jarrett Billingsley wrote:

On Tue, Apr 28, 2009 at 10:23 PM, Daniel Keep
 wrote:


That requires f to be a type, which loses you the actual names.  And you
cannot (last time I checked) have aliases in a tuple.


Check again - tuples can be any arbitrary mix of types, expressions,
and aliases.  :)


Wow, it actually works. But I really don't understand why. It seems the 
compiler directly passes symbols as tuple arguments, and later dumbs it 
down to what it needs (like an alias, a type, ...).


Makes me think nobody will ever be able to write a separate bug-free DMD 
frontend. I'm scared.


Re: Get the name of a function and the parameters?

2009-04-28 Thread grauzone

Jarrett Billingsley wrote:

On Sun, Apr 26, 2009 at 12:23 PM, Jacob Carlborg  wrote:

Is it possible to get the name of a function and the names of the function
parameters?


Name of a function?  Yes.

public template NameOfFunc(alias f)
{
version(LDC)
const char[] NameOfFunc = (&f).stringof[1 .. $];
else
const char[] NameOfFunc = (&f).stringof[2 .. $];
}

debug
{
private void _foo_(){}
static assert(NameOfFunc!(_foo_) == "_foo_", "Oh noes, NameOfFunc
needs to be updated.");
}

It has to be used at compile time with an alias of course, but it works.


I'd like to pass several functions at once. Is there a way to make this 
variadic? The obvious approach (writing "NameOfFunc(alias f...)") fails 
with a syntax error.



Name of params?  No, not that I've found.  Sometimes the compiler will
give parameter names of functions declared with tuple parameters in
error messages; I wonder if that could be abused.

Don't you love it?  "Most C++ template features are discovered."  So are D's.


Re: static initialization of associative arrays

2009-04-15 Thread grauzone

 What's the advantage of doing this? Having quicker startup times?



Syntax. Read the first post of this thread.


Re: clone method of Object

2009-04-15 Thread grauzone

bearophile wrote:

grauzone:

the clone method will only copy member b, but not a or c.


A *good* implementation of this function seems fit to be added to Phobos.


And serialization, and a complete reflection API.


Bye,
bearophile


Re: clone method of Object

2009-04-15 Thread grauzone

There are two things on my side:
1. Compiler refuses to clone private attributes. I have tried
gdc/gdmd/dmd_v1 in Linux.


It was changed in dmd later, and now you can access private attributes 
by using tupleof. I don't know when exactly it was changed, but it 
should work at least with dmd 1.039 and later. GDC probably uses an 
ancient front-end version, and I think nobody should use it.


Re: clone method of Object

2009-04-15 Thread grauzone

Qian Xu wrote:

grauzone wrote:

newobject.tupleof[i] = old.tupleof[i];


If the current value of tupleof[i] is an object, the object will be
referenced, won't it?

Shall I write:

  auto elem = old.tupleof[i];
  static if (is(typeof(elem) == class))
  {
 newobject.tupleof[i] = clone(elem);
  }
  else
  {
 newobject.tupleof[i] = elem;
  }


Object graphs often contain circular references liker this:

class A {
B b;
}

class B {
A a;
}

auto a = new A();
auto b = new B();
a.b = b;
b.a = a;

Your recursive approach wouldn't quite work with that. Before cloning an 
object, you'll first have to check if the object was already cloned. If 
this is the case, use the previously created clone instead of making a 
new clone.






--Qian


Re: clone method of Object

2009-04-15 Thread grauzone

grauzone wrote:

Qian Xu wrote:

Hi All,

is there any (easy) way to clone an object or any other classes?


--Qian


Simple answer: No.

Complicated answer: Yes, but you have to write it yourself.

Here's a nice starting point. You can use tupleof to get all members of 
a class. Note that this doesn't deal with superclasses, and members of 
superclasses are not copied:


T clone(T)(T old) {
auto newobject = new T();
foreach (int i, _; old.tupleof) {
newobject.tupleof[i] = old.tupleof[i];
}
return newobject;
}

cloned = clone(yourobject);


I should add that members of subclasses are not copied either. E.g. if 
you have


class A {int a;}
class B : A {int b;}
class C : B {int c;}

B someobject;
clone(someobject);

the clone method will only copy member b, but not a or c.


Re: clone method of Object

2009-04-15 Thread grauzone

Qian Xu wrote:

Hi All,

is there any (easy) way to clone an object or any other classes?


--Qian


Simple answer: No.

Complicated answer: Yes, but you have to write it yourself.

Here's a nice starting point. You can use tupleof to get all members of 
a class. Note that this doesn't deal with superclasses, and members of 
superclasses are not copied:


T clone(T)(T old) {
auto newobject = new T();
foreach (int i, _; old.tupleof) {
newobject.tupleof[i] = old.tupleof[i];
}
return newobject;
}

cloned = clone(yourobject);



Re: Indexing an associative array with a list of types

2009-04-11 Thread grauzone

What exactly are you trying to accomplish?

It seems that you want to use the AA in CTFE, but it doesn't work, 
because using AAs with classes as keys don't work in CTFE?


Re: Indexing an associative array with a list of types

2009-04-11 Thread grauzone

Doctor J wrote:

I'd like to make a compile-time constant associative array mapping a list of 
types to an integer:

int[??] typemap;

typemap[(int,float)] = 1;
typemap[(long,double)] = 2;
...
int t = typemap[(int,float)];

I tried playing with std.typetuple but no luck.  I can get halfway there with a 
function template, but then I can't iterate over the keys or values.  Is there 
a way to do something like this in D?  More generally, is there a way to store 
a type in a variable?



Just curious, how did you do this function template thing?


Thanks.



Types are a compiletime only thing. To get a "runtime" handle for a 
type, use TypeInfo. For each type, there exists exactly one TypeInfo 
object instance. You can get this object with typeid():


TypeInfo ti = typeid(int);

Your example above could actually be implemented like this:

int[TypeInfo[]] typemap;

typemap[[typeid(int), typeid(float)]] = 1;

(Two [] bracket pairs because one is for indexing into the AA, and one 
is an array delegate for constructing the TypeInfo[] array, which is 
used as key.)


Re: Class templates with types determined at runtime

2009-04-07 Thread grauzone

Not sure what you're actually trying to do, but you can do this:

class Container {
abstract void dostuff();
}

class ContainerSDgsdg(T) : Container {
override void dostuff() {
//can use T here
}
}

Container bla = new ContainerSDgsdg!(int)();
//can pass around "bla" freely, because class Container is not
//templated! the actual class is, but this doesn't matter.
bla.stuff();


Re: Format.convert problme

2009-04-06 Thread grauzone

Qian Xu wrote:

grauzone wrote:


Check if the variable is a pointer, and if yes, dereference it:

alias typeof(i) T;
static if (is(T T2 : T2*)) {
T2 i2 = *i;
Format.convert("{}", i2);
} else {
Format.convert("{}", i);
}


Hi again,

I cannot compile this code 


What exactly are you doing? What do you want to do? Without knowing 
this, we can only guess. My first reply to you was also just a guess. I 
thought maybe you had a templated function, and wanted to dump a 
templated variable, or so.


Anyway, here's a complete version of my example above. It uses 
Stdout.formatln instead of Format.convert, but this shouldn't matter at all.


import tango.io.Stdout;

void main() {

int v = 55;
int *pv = &v;

//pv (an int pointer) can be exchanged with v (an int),
//and it still works
auto i = pv;

alias typeof(i) T;
static if (is(T T2 : T2*)) {
T2 i2 = *i;
Stdout.formatln("{}", i2);
} else {
Stdout.formatln("{}", i);
}

}


Re: Format.convert problme

2009-04-04 Thread grauzone

Qian Xu wrote:

Hi All,

tango.text.convert.Format provides a nice function to convert anything 
to string.


It works perfect except the argument is a pointer type.
It will print the address of a pointer instead of its value

For instance: 
int* i = new int;
*i = 10;
Format.convert("{}", i); // <- the address of the pointer
--

How to let it print the value instead of the address?
Because I wanna write a dump function to dump the value of any data type 
(also void, null)


Check if the variable is a pointer, and if yes, dereference it:

alias typeof(i) T;
static if (is(T T2 : T2*)) {
T2 i2 = *i;
Format.convert("{}", i2);
} else {
Format.convert("{}", i);
}


Re: What's the purpose of the -v1 switch?

2009-04-01 Thread grauzone

Jarrett Billingsley wrote:

On Wed, Apr 1, 2009 at 12:01 PM, Trass3r  wrote:

I mean it can only be used with dmd 1.x compilers anyway.

else if (strcmp(p + 1, "v1") == 0)
{
#if DMDV1
   global.params.Dversion = 1;
#else
   error("use DMD 1.0 series compilers for -v1 switch");
   break;
#endif
}



It turns off the features which were added to D1 after 1.000.  Things
like the 'ref' and 'macro' keywords, string mixins, import
expressions, changes to .init etc.


So, technically, we already have a D 1.1?


Re: About alias

2009-03-31 Thread grauzone

Trass3r wrote:

Sam Hu schrieb:
I am confused again this time about the key word alias when I read 
below tutorial:

http://www.dsource.org/projects/tutorials/wiki/MetaBinarySearch
Let's say this one:
template bSearch(alias Match, alias Fail, alias x, A...) {
const bSearch = bSearchAlg!(0,Match,Fail,x,A);
}

what is the meaning of the 'alias ' before parm Match in the parms 
list,and what's the purpose?




http://www.digitalmars.com/d/2.0/template.html#TemplateAliasParameter
Be aware that alias parameters are only available in D2.0.


Wrong:
http://www.digitalmars.com/d/1.0/template.html#TemplateAliasParameter


Re: dump object

2009-03-30 Thread grauzone

Qian Xu wrote:

Hi All,

previously I saw an article about how to dump an object with all properties.

-code---
void log(T)(T obj) {
  static if (is(T == struct) || is(T == class)){
 writef("{");
 foreach(i,_;obj.tupleof) {
   writefln("%s : %s,", obj.tupleof[i].stringof[4..$], obj.tupleof[i]);
 }
 writefln("}");
  }
  else {
 writefln(obj);
  }
}
-code---


But this function does not work with private attributes of an object.

How to print all public properties of an object?
It would be very useful for debug propose.


Use a newer compiler version. dmd 1.041 should work. I'm successfully 
using this feature for serialization.




Best regards
--Qian


Re: LPT

2009-03-25 Thread grauzone

Jarrett Billingsley wrote:

On Wed, Mar 25, 2009 at 5:00 PM, Jarrett Billingsley
 wrote:

On Wed, Mar 25, 2009 at 4:21 PM, Zarathustra  wrote:

Have you got any idea how to manipulate LPT port in Windows XP with D?


Um, the same way you'd do it with any other language...?


I mean, if you computer even _HAS_ an LPT port.  I haven't seen one in years.


My computer is only a year old and has one LPT and two serial ports. The 
only traditional thing that's missing is a floppy drive.


Re: How to reduce compile times?

2009-03-23 Thread grauzone

Jarrett Billingsley wrote:

On Sat, Mar 21, 2009 at 3:45 PM, grauzone  wrote:

Also, I noticed that "dsss build -full" seems to be the way to pass this
flag on the command line. But the project is recompiled even when no file
was modified at all. This is not good: it should only recompile if something
has changed.


Why would you recompile if you haven't changed anything?  :P


I want to build system to recompile the program automatically before I 
execute it. Doing this manually is not an option, because it's annoying 
and I could forget it.


Re: How to reduce compile times?

2009-03-21 Thread grauzone

Brian wrote:

On Sat, 21 Mar 2009 15:44:41 +0100, grauzone wrote:


I'm using dsss (with dmd under Linux) to compile my project, and
build/compile times are reaching unacceptable highs.


out of curiosity, how much code do you actually have? im using D for 
something with ~12,000 lines of code right now, spread among 40 files or 
so, with a somewhat excessive use of CTFE and templates all over. a full 
rebuild takes about 5 seconds with incremental builds taking 1 or 2 
seconds in most cases.


i just wanted to know what "excessively high" means

P.S. using dmd 1.036, rebuild 0.78, phobos, linux


65906 physical lines of code (+ some Tango .di imports + some small 
external libraries), maybe 200+ files, takes 1m10s to build when using 
normal dsss. With -full and oneatatime=no, compile time goes down to 6-7 
seconds. It's not that template- and CTFE-heavy.


Incremental builds can take relatively long (depending where the changed 
files are in the dependency tree), and it's really annoying.


Re: How to reduce compile times?

2009-03-21 Thread grauzone
I use bud, which builds everything with a single run of dmd, but uses 
incremental compilation.  If I get linker errors, I just run my cleanup 
script and try again.  Or add -full to bud's command line.


In my case, this practically always causes linker errors. Of course I 
don't know why.


Re: How to reduce compile times?

2009-03-21 Thread grauzone

Jarrett Billingsley wrote:

On Sat, Mar 21, 2009 at 2:50 PM, grauzone  wrote:


What I need is to make dsss completely recompile the project, even if only a
single source file was modified. This way, no errors should occur, and it
would still be faster than with oneatatime=yes.


-full


Sorry for being so helpless, but where do I add this to the rebuild 
configfile?


Also, I noticed that "dsss build -full" seems to be the way to pass this 
flag on the command line. But the project is recompiled even when no 
file was modified at all. This is not good: it should only recompile if 
something has changed.


Re: How to reduce compile times?

2009-03-21 Thread grauzone

Christopher Wright wrote:

grauzone wrote:
PS: another thing that possibly would bring a speed gain would be to 
make dsss compile the whole project in one run, instead of invoking a 
new dmd process for each source file. How do I need to change the 
rebuild configuration to achieve this?


oneatatime = [yes|no]

You want 'no'. This will occasionally produce issues with ModuleInfo not 
being defined with some dmd versions, I think. Or something like that.


Yes, this causes random linker errors.

What I need is to make dsss completely recompile the project, even if 
only a single source file was modified. This way, no errors should 
occur, and it would still be faster than with oneatatime=yes.


(Damn that crappy support for incremental compilation.)


Re: DSSS verbose mode?

2009-03-21 Thread grauzone

The closest thing that I know is "dsss build -v"


How to reduce compile times?

2009-03-21 Thread grauzone
I'm using dsss (with dmd under Linux) to compile my project, and 
build/compile times are reaching unacceptable highs.


What are some tips to speed up the build process?

For example, I could imagine that heavy use of templates and CTFE slows 
the compiler down. Maybe string mixins with CTFE on the module level are 
most expensive: here, the compiler has to do heavy weight semantic 
analysis every time a module is imported from another module (maybe even 
recursively). But I don't really know; it depends too much on how the 
compiler works internally.


Without some kind of "build profiler", I have no clue what is actually 
causing slow downs. It's like groping in the dark!


The only thing that comes near to this seems to be to insert a 
"pragma(msg, blabla)" at random points in your modules. Then you 
recompile the project and count how many times the message is outputted.


Actually, the whole issue seems to boil down to reducing module 
dependencies. But then again, your "main" module recursively depends 
from _all_ used modules in your project.


What I personally found useful in practice is to reduce the number of 
interdependent modules by separating them into interface and 
implementation modules, e.g. by using delegates or inheritance. Then you 
can "hide" the implementation from most modules by removing the static 
dependencies. But this only works in some cases, and is always inconvenient.


PS: another thing that possibly would bring a speed gain would be to 
make dsss compile the whole project in one run, instead of invoking a 
new dmd process for each source file. How do I need to change the 
rebuild configuration to achieve this?


Re: Universel toString

2009-03-20 Thread grauzone

Daniel Keep wrote:


Qian Xu wrote:

Hi All,

I want to write an universel toString() method for debugging propose.
However I cannot write in one version. The compiler says error all the time.
Could someone tell me, how to write an universel one?

What I want, is to convert primtive types (int, int*, bool, bool*, etc.) to
string using "tango.text.Convert.to()" and convert object to string by
calling obj.toString.

...

Best regards
--Qian Xu


to!(char[]) should call toString.  to!(T) should support all atomic
types, strings, structs and classes.


So to!(char[])(x) almost like format("%s", x)?


  -- Daniel


Re: Char[] confusing

2009-03-02 Thread grauzone

Qian Xu wrote:

Lutger wrote:

s[4] means the fifth element of s[]
s[0..4] is a slice from the first to the fifth, but not including the 
fifth element. The last element in a slice is always one past the end 
of that slice.


Thank you both.
I have to do math in mind in order to keep my code correct ;-)


IMO, it does not make any sense.
s[start..end]

  end - is neither the count of characters in the array slice,
   nor the end index of the slice.
it is just the index after the real end character.



Think of it as "everything in the string before this."


Re: chaining

2009-02-26 Thread grauzone

Brian wrote:
I want to use a chaining system for easy setting of object attributes, 
which would work great for a single object, unfortunately derived classes 
cannot inherit the chained functions implicitly, whats the best way 
around this?


class Base {
int x;
Base foo(int x_) {
this.x = x_;
return this;
}
}

class Derived : Base {
Derived bar(int y_) {
return this;
}
}

// usage:
auto m = (new Derived).foo(10).bar(x); // bar can be accessed through foo


Couldn't you just write the above example as:

auto m = new Derived;
m.foo(10);
m.bar(x);

This is actually much more readable: the reader doesn't need to know 
that the functions foo and bar return m; instead, the code uses m 
directly. Obviously, this is also simpler to implement than chaining.


I don't get why some people like chaining. Unlike in languages like C++, 
you can always use "auto" to keep the typing to a minimum. What more 
arguments are there for chaining?


Re: Dynamic Array Garbage collection

2009-02-24 Thread grauzone

Jarrett Billingsley wrote:

On Tue, Feb 24, 2009 at 10:42 PM, Daniel Keep
 wrote:

You missed the array literal.

I saw that, but thought that it would be a short[] literal since it's
usually the type of the first argument.


Odd, it works.  And properly too.


Could it be because of integer promotion rules?


I give up on trying to figure out what the compiler does to figure out
the type of array literals :P


Re: "Symbol undefined" on interface with public getter and package setter

2009-02-23 Thread grauzone
Last time I checked I could even use "override" to... erm, override 
methods that had package protection. The compiler didn't even complain, 
and I had to find out the hard way that the method wasn't virtual.


Re: Encoding of eol in multiline wysiwyg strings

2009-02-17 Thread grauzone

Jarrett Billingsley wrote:

On Tue, Feb 17, 2009 at 4:41 AM, KlausO  wrote:

Hello,

does the D specification specify how the "end of line" is encoded when you
use wysiwyg strings. Currently it seems to be '\n' on windows
(And I guess it will '\n' on linux, too.).
Is this the intended behaviour ?


http://www.digitalmars.com/d/1.0/lex.html

"Wysiwyg Strings

Wysiwyg quoted strings are enclosed by r" and ". All characters
between the r" and " are part of the string except for EndOfLine which
is regarded as a single \n character."


It's not a big issue but somtimes when you use wysiwyg strings, string
concatenation and import expressions to combine some text the result is a
string with mixed EOL encodings.
Thanks for clarifying,


It's the import() expression that's messing things up.  It just loads
the file verbatim and does no line-ending conversions.


But many people would like to use import() to read binary data.

I guess one could extend the language specification to solve this:

//load, convert line endings, check for valid UTF-8
char[] import_text(char[] filename);

//return unchanged file contents as byte array
ubyte[] import_binary(char[] filename);

On the other hand, both could be implemented as compile-time functions 
using the current import().


Re: get a struct member pointer

2009-02-16 Thread grauzone

bearophile wrote:

Daniel Keep:

void lookup(T)(T[] s, size_t offset)
{
  char[] text = *cast(char[]*)(cast(void*)(&s[0]) + offset);
}


I am learning still this topic, but can't this create an aliasing problem, as 
in C?
http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html


My theory is, that Walter's code generator is too primitive to care 
about aliasing. But I guess it's possible, that aliasing rules will be 
added later to the language, when LDC (hopefully) gets big?


By the way, wtf is Daniel's code doing at all?


Bye,
bearophile


Re: Internal error: ..\ztc\evalu8.c 2093

2009-02-11 Thread grauzone

John Reimer wrote:

Hello Zarathustra,


When I trying build dwt-win 3.4.1 I get the following error:
Internal error: ..\ztc\evalu8.c 2093
command line:
dsss build
I using DSSS 0.78, Tango 0.99.7 with DMD 1.033.
OS: Windows XP
Any ideas?




Can you try a more recent compiler... like dmd 1.037?


Also, I would highly recommend /not/ using DSSS version 0.78.  I suggest 
you use 0.75.  You can use 0.78 if you enjoy looong build times. :)


I still use dsss 0.75, because it's the only dsss version, which can 
build my project without generating linker errors all the time.


I also see that you recommend dmd 1.037. That's funny, because that's 
the latest "stable" version for me as well. Later dmd versions just go 
into an infinite loop or so when compiling my project.




-JJR




Re: Compare two objects

2009-02-10 Thread grauzone

Qian Xu wrote:

Hi All,

I want to test, if two objects are equal. 
The rules are as follows: 
1. When both are null, it should return true. 
2. When one of them is null, it should return false.

3. When both not null, then compare their values (as two strings)

My test code
---
class Test {
  private int value;
  this(int value) {
this.value = value;
  }
  public int getValue() {
return this.value;
  }
  bool opEquals(Test obj) {
if (obj is null) {
  return this is null;
}
return this.getValue() == obj.getValue();
  }
}

procedure test(Test a, Test b) {
  if (a is null && b is null) return true;
  if (a !is null && a == b) return true;
  return false;
}

void main()
{
  Test a;
  Test b = new Test(100);
  assert(test(a, b)); // ok
  assert(a != b); // av error
}


If object at the left side of the != is null, I will get an AV error
immediately.
If I want to compare two objects safely, I have to write my own test(..)
function.
But this is not nice.

Can someone explain, is this a design shortcoming of D-Compiler, or I am
wrong.


It's a shortcoming in the design of the == operator. Code like "a==b" 
will always be compiled to this:

> a.opEquals(b)
If a is null, the call will always cause a segfault. You simply can't 
call a method on a null object. There are two reasons for this: 1. it 
will dereference the object's vtable to look up virtual methods and 2. 
the runtime will try to call the object's invariant, which segfaults 
too. (Actually, I see an assert with a null check in _d_invariant(). But 
somehow, gdb usually still shows a segfault in _d_invariant(). Maybe 
Phobos isn't compiled in debug mode.)


The D compiler even has a special rule to disallow compilation of code 
like "a==null" (yes, because of the null literal). It seems Walter added 
this, because people were using this code to check if an object is null.


Conclusion: == is absolutely useless in your case. Use something else.


Best regards
--Qian Xu





Re: Time some code using Tango

2009-02-03 Thread grauzone

Jarrett Billingsley wrote:

On Tue, Feb 3, 2009 at 5:54 PM, Matthias Walter
 wrote:

Hi there,

I'd like to time some functions using Tango, but only including the really used 
CPU-time. StopWatch and the other time functions I've found don't mind on the 
CPU usage, which means if I time multiple processes at once which share a 
single CPU, their times increase...

Best regards
Matthias Walter



That's something that the OS could do for you, like the "timex"
command on unix.  There's probably something magical in /proc/ that
you can use.  I have no idea what the corresponding functionality
would be in Windows, but it probably has something.


If he had to use OS specific APIs (which would be another sad thing 
about Tango), I'd suggest to use clock_gettime() with 
CLOCK_THREAD_CPUTIME_ID under Unix.


What is timex?


Re: Some performance questions

2009-02-02 Thread grauzone
I agree. Of course using an interface to call a method always requires a 
virtual method call. It's even slower than a virtual method call, 
because it needs to convert the interface reference into an object 
reference.


But he still could call the method in question directly. Implementing an 
interface can be useful to enforce a contract. You can't do that with 
structs.


Code compiled in debug mode (or was it not-release mode) also calls the 
code to check the invariant, even if you didn't define one. I guess this 
can make calling struct methods much faster than object methods.


Re: Some performance questions

2009-02-02 Thread grauzone

Jarrett Billingsley wrote:

On Mon, Feb 2, 2009 at 3:11 PM, Chris Nicholson-Sauls
 wrote:

Or he's caching some very big/complex parameters in the code he's actually
writing... maybe. That said: do we have any assurance that, were the functor
class tagged as 'final', the call would cease to be virtual?  If so, then
the only extra cost on the call is that of the hidden "this" sitting in ESI.
 I still don't care for the memory allocation involved, personally, but if
these are long-lived functors that may not be a major problem.  (Ie, if he
calls foo(?,X) a million times, the cost of allocating one object is
amortized into nearly nothing.)


Oh, I suppose I should also point out that if you made these functors'
methods final, they wouldn't be able to implement interfaces, since
interface implementations must be virtual.  So, at that point, you're
using a final scope class - might as well use a struct anyway.


As far as I know, interface methods can still be final methods in a 
class. final methods are only disallowed to be overridden further. But 
it's perfectly fine to mark a method final, that overrides a method from 
a super class. final so to say only works in one direction.


Then the compiler can optimize calls, if they are statically known to be 
final. If not, it still has to do a vtable lookup on a method call, even 
if the actually called method is final.


So it can still make sense to use a class instead of a struct.


Re: Some performance questions

2009-02-02 Thread grauzone

Jarrett Billingsley wrote:

On Mon, Feb 2, 2009 at 8:31 AM, Lars Kyllingstad
 wrote:

I have some functions for which I want to find the nicest possible
combination of performance and usability. I have two suggestions as to how
they should be defined.

"Classic" style:

   real myFunction(real arg, int someParam, inout real aReturnValue)
   {
   declare temporary variables;
   do some calculations;
   store a return value in aReturnValue;
   return main return value;
   }

The user-friendly way, where the function is encapsulated in a class:

   class MyFunctionWorkspace
   {
   declare private temporary variables;

   real anotherReturnValue;

   this (int someParam)
   { ... }

   real myFunction(real arg)
   {
   do some calculations;
   store a return value in aReturnValue;
   return main return value;
   }
   }

I'm sure a lot of people will disagree with me on this, but let me first say
why I think the last case is more user-friendly. For one thing, the same
class can be used over and over again with the same parameter(s). Also, the
user only has to retrieve aReturnValue if it is needed. If there are many
such "additional" inout parameters which are seldom needed, it gets tedious
to declare variables for them every time the function is called. I could
overload the function, but this also has drawbacks if there are several
inout parameters with the same type.

My questions are:

- If I do like in the second example above, and reuse temporary variables
instead of allocating them every time the function is called, could this way
also give the best performance? (Yes, I know this is bad form...)

...or, if not...

- If I (again in the second example) move the temporary variables inside the
function, so they are allocated on the stack instead of the heap (?), will
this improve or reduce performance?

I could write both types of code and test them against each other, but I am
planning to use the same style for several different functions in several
modules, and want to find the solution which is generally the best one.


Any gains you get from skipping the initial calculations will be
swiftly cut down by the cost of heap allocation and cache misses, if
you allocate this object several times.

A much better way to get the usability of the latter with the better
performance of the former is to use a struct instead of a class.  I
highly doubt you'll be needing to inherit these "operation objects"
anyway.  The struct will be allocated on the stack, and you still get
all the usability.


Why not use scope to allocate the class on the stack?
For everything else, I agree with Donald Knuth (if he really said that...)


Re: foreach/opApply is the visitor pattern

2009-02-01 Thread grauzone

BCS wrote:
Correct me if I'm wrong but I thing that D's opApply is a form of the 
Visitor pattern where the calling function's stack frame is the visitor 
object.


This just occurred to me. Maybe I've been missing something re the 
visitor pattern but I think this make for a nice, cool and easy way to 
describe it. (Also I don't remember it being described that way)


More importantly, why does it matter?


Re: foreach/opApply is the visitor pattern

2009-02-01 Thread grauzone

BCS wrote:

Hello Robert,


BCS wrote:


Correct me if I'm wrong but I thing that D's opApply is a form of the
Visitor pattern where the calling function's stack frame is the
visitor object.

This just occurred to me. Maybe I've been missing something re the
visitor pattern but I think this make for a nice, cool and easy way
to describe it. (Also I don't remember it being described that way)


Er no. There's no double-dispatch (at least automatically),
there's only one foreach body delegate. The visitor pattern as far as
I know it uses dynamic dispatch so the visitor object can handle
different objects in the class hierarchy differently. For example, you
couldn't use a foreach to enumerate through a syntax tree and handle
expressions and statements differently (well, you could, but you'd
have to do it manually).



OK I'll grant that it doesn't follow the normal pattern to the letter 
but it can be viewed as a degenerate case where there is only one 
visitable type.


Does that mean all function calls are a degenerate case of the visitor 
pattern?


Re: Segmentation error at the end problem (148 line program listing)

2009-01-31 Thread grauzone

Daniel Keep wrote:


grauzone wrote:

The garbage collector isn't guaranteed to to free and destroy an
unreachable object. That's because the GC is conservative. So if you
want to be sure the object's resources are freed, you have to do it
explicitly.

I think you have two choices:
1. Remove close() from the destructor, and call close() manually when
you're done.
2. Use scope or delete to ensure the destructor is always directly
called, and never by the GC.


Here's how you can use scope:

{
scope BlockFile f = new BlockFile(...);
//... do something with f
} //f goes out of scope, and the compiler inserts delete f;


If you're going to do that, you really should make the it a scope class
to ensure you never accidentally let the GC try to delete it.

I (and a few others) petitioned what feels like years ago for a simple
argument to dtors to distinguish between deterministic destruction
(delete/scope) and automatic destruction (GC).  Never gained any ground,
sadly.


I think it'd be even better to make them different functions. The 
finalizer could just be a virtual function called finalize(). Really, 
the differences between proper destructors and finalizers should be 
large enough to justify separate functions.


Or even better, ditch finalizers and their wacky semantics (which make 
them quite useless anyway), and invent something like notify-able 
weakpointers. D already provides basic support for this 
(Object.notifyRegister()), but I think in Phobos 1.0 it's a bit buggy. 
There were some issues with race conditions and locking.


Re: Segmentation error at the end problem (148 line program listing)

2009-01-31 Thread grauzone
The garbage collector isn't guaranteed to to free and destroy an 
unreachable object. That's because the GC is conservative. So if you 
want to be sure the object's resources are freed, you have to do it 
explicitly.


I think you have two choices:
1. Remove close() from the destructor, and call close() manually when 
you're done.
2. Use scope or delete to ensure the destructor is always directly 
called, and never by the GC.



Here's how you can use scope:

{
scope BlockFile f = new BlockFile(...);
//... do something with f
} //f goes out of scope, and the compiler inserts delete f;


Re: Segmentation error at the end problem (148 line program listing)

2009-01-30 Thread grauzone

Charles Hixson wrote:

I replaced BlockFile.close with:
   void  close()
   {  if (bf !is null)  delete bf;//bf.close;
  bf =  null;
   }

But that didn't alter the segmentation fault.  (Did you try it under D1 
or D2?)


Your destructor calls close(), and close() accesses the reference bf. 
But accessing references is not allowed in destructors. I think "delete 
bf;" still counts as accessing a reference.


The reason is, that the garbage collector calls the destructor, when an 
object becomes unreachable. The order the destructors are called is 
undefined. References to other objects may no longer be valid, because 
these objects were already destroyed.


Accessing private class members with tupleof

2009-01-29 Thread grauzone
Is it legal to access private members of a class using tupleof, when 
normal access would be illegal?


It is not really clear from the D1.0 specification:

> The .tupleof property returns an ExpressionTuple of all the fields in
> the class, excluding the hidden fields and the fields in the base
> class.

Do private members count as hidden, or does the specification only 
consider the vtable and monitor fields as hidden fields? What exactly 
are "hidden fields" at all?


It seems newer dmd versions allow you to access private members, while 
older versions raise a compile-time error.


Here is an example to demonstrate the issue (for D1.0):

---file a.d

module a;

class Test {
int a = 1;
protected int b = 2;
private int c = 3;
package int d = 4;
}

---file b.d

module b;

import a;

int[] get(Test t) {
int[] result;
foreach (i, x; t.tupleof) {
result ~= t.tupleof[i];
}
return result;
}

import std.stdio;

void main() {
//outputs [1,2,3,4]
writefln(get(new Test()));
}


Re: Prevent default-initialised struct

2009-01-28 Thread grauzone
I think it would really suck to introduce special cases to forbid 
default initialization of structs. And assuming T was the type of the 
struct, what would T.init do? Or typeid(T).init()?


Use a class instead.

If you really need a struct, you could use a private field, that signals 
if the struct was properly initialized.


E.g.

struct Foo {
debug private bool initialized;

static Foo opCall() {
Foo n;
debug n.initialized = true;
return n;
}

void foo() {
assert (initialized);
//do something useful
}
}