odd behavior of split() function

2013-06-07 Thread Bedros

I would like to split "A+B+C+D" into "A", "B", "C", "D"

but when using split() I get

"A+B+C+D", "B+C+D", "C+D", "D"


the code is below


import std.stdio;
import std.string;
import std.array;

int main()
{
 string [] str_list;
 string test_str = "A+B+C+D";
 str_list = test_str.split("+");
 foreach(item; str_list)
 printf("%s\n", cast(char*)item);

 return 0;
}


Re: odd behavior of split() function

2013-06-07 Thread Jonathan M Davis
On Friday, June 07, 2013 09:18:57 Bedros wrote:
> I would like to split "A+B+C+D" into "A", "B", "C", "D"
> 
> but when using split() I get
> 
> "A+B+C+D", "B+C+D", "C+D", "D"
> 
> 
> the code is below
> 
> 
> import std.stdio;
> import std.string;
> import std.array;
> 
> int main()
> {
>   string [] str_list;
>   string test_str = "A+B+C+D";
>   str_list = test_str.split("+");
>   foreach(item; str_list)
>   printf("%s\n", cast(char*)item);
> 
>   return 0;
> }

That would be because of your misuse of printf. If you used

foreach(item; str_list)
writeln(item);

you would have been fine. D string literals do happen to have a null character 
one past their end so that you can pass them directly to C functions, but D 
strings in general are _not_ null terminated, and printf expects strings to be 
null terminated. If you want to convert a D string to a null terminated 
string, you need to use std.string.toStringz, not a cast. You should pretty 
much never cast a D string to char* or const char* or any variant thereof. So, 
you could have done

printf("%s\n", toStringz(item));

but I don't know why you'd want to use printf rather than writeln or writefln - 
both of which (unlike printf) are typesafe and understand D types.

You got

"A+B+C+D", "B+C+D", "C+D", "D"

because the original string (being a string literal) had a null character one 
past its end, and each of the strings returned by split was a slice of the 
original string, and printf blithely ignored the actual boundaries of the 
slice looking for the next null character that it happened to find in memory, 
which - because they were all slices of the same string literal - happened to 
be the end of the original string literal. And the strings printed differed, 
because each slice started in a different portion of the underlying array.

- Jonathan M Davis


Re: geting stack trace from signal handlers

2013-06-07 Thread nazriel

On Thursday, 6 June 2013 at 21:50:58 UTC, Timothee Cour wrote:

Great!
two issues (on OSX at least):

A)
it seems the top-most element of the call stack gets chopped 
off; eg in
your code, the main_module.main symbol will not appear in the 
stack trace.

Any idea why or how to fix that?
Is that some inlining issue ? I tried with dmd -g, or -gs or 
-gc.
This can be annoying when the top-most function is a large 
function and

it's not at all clear where the code stopped.

I haven't got Mac OSX to test it out but I fixed it a little bit 
so it is less hacky:


http://dpaste.dzfl.pl/241c6fb5

Compiler switches you may want to consider are:
-gc -L--export-dynamic -O0


B)
there are no line numbers. I did a complex workaround by 
launching a
process and calling atos to get those, but isn't there a better 
way?


Yeah, it is a complex issue. There are 2 ways to fix it from what 
I know.

1) pipe addresses to addr2line - easier
2) use libdwarf - more complex but also more out-of-box solution




Re: odd behavior of split() function

2013-06-07 Thread Bedros

first of all, many thanks for the quick reply.

I'm learning D and it's just because of the habit I unconsciously 
used printf instead of writef


thanks again.

-Bedros

On Friday, 7 June 2013 at 07:29:48 UTC, Jonathan M Davis wrote:

On Friday, June 07, 2013 09:18:57 Bedros wrote:

I would like to split "A+B+C+D" into "A", "B", "C", "D"

but when using split() I get

"A+B+C+D", "B+C+D", "C+D", "D"


the code is below


import std.stdio;
import std.string;
import std.array;

int main()
{
  string [] str_list;
  string test_str = "A+B+C+D";
  str_list = test_str.split("+");
  foreach(item; str_list)
  printf("%s\n", cast(char*)item);

  return 0;
}


That would be because of your misuse of printf. If you used

foreach(item; str_list)
writeln(item);

you would have been fine. D string literals do happen to have a 
null character
one past their end so that you can pass them directly to C 
functions, but D
strings in general are _not_ null terminated, and printf 
expects strings to be
null terminated. If you want to convert a D string to a null 
terminated
string, you need to use std.string.toStringz, not a cast. You 
should pretty
much never cast a D string to char* or const char* or any 
variant thereof. So,

you could have done

printf("%s\n", toStringz(item));

but I don't know why you'd want to use printf rather than 
writeln or writefln -
both of which (unlike printf) are typesafe and understand D 
types.


You got

"A+B+C+D", "B+C+D", "C+D", "D"

because the original string (being a string literal) had a null 
character one
past its end, and each of the strings returned by split was a 
slice of the
original string, and printf blithely ignored the actual 
boundaries of the
slice looking for the next null character that it happened to 
find in memory,
which - because they were all slices of the same string literal 
- happened to
be the end of the original string literal. And the strings 
printed differed,
because each slice started in a different portion of the 
underlying array.


- Jonathan M Davis




Re: odd behavior of split() function

2013-06-07 Thread Benjamin Thaut

Am 07.06.2013 09:53, schrieb Bedros:

first of all, many thanks for the quick reply.

I'm learning D and it's just because of the habit I unconsciously used
printf instead of writef

thanks again.

-Bedros

On Friday, 7 June 2013 at 07:29:48 UTC, Jonathan M Davis wrote:

On Friday, June 07, 2013 09:18:57 Bedros wrote:

I would like to split "A+B+C+D" into "A", "B", "C", "D"

but when using split() I get

"A+B+C+D", "B+C+D", "C+D", "D"


the code is below


import std.stdio;
import std.string;
import std.array;

int main()
{
  string [] str_list;
  string test_str = "A+B+C+D";
  str_list = test_str.split("+");
  foreach(item; str_list)
  printf("%s\n", cast(char*)item);

  return 0;
}


That would be because of your misuse of printf. If you used

foreach(item; str_list)
writeln(item);

you would have been fine. D string literals do happen to have a null
character
one past their end so that you can pass them directly to C functions,
but D
strings in general are _not_ null terminated, and printf expects
strings to be
null terminated. If you want to convert a D string to a null terminated
string, you need to use std.string.toStringz, not a cast. You should
pretty
much never cast a D string to char* or const char* or any variant
thereof. So,
you could have done

printf("%s\n", toStringz(item));

but I don't know why you'd want to use printf rather than writeln or
writefln -
both of which (unlike printf) are typesafe and understand D types.

You got

"A+B+C+D", "B+C+D", "C+D", "D"

because the original string (being a string literal) had a null
character one
past its end, and each of the strings returned by split was a slice of
the
original string, and printf blithely ignored the actual boundaries of the
slice looking for the next null character that it happened to find in
memory,
which - because they were all slices of the same string literal -
happened to
be the end of the original string literal. And the strings printed
differed,
because each slice started in a different portion of the underlying
array.

- Jonathan M Davis




You can use printf if you want to, the correct usage is not so nice though:

string str = "test";
printf("%.*s", str.length, str.ptr);

Kind Regards
Benjamin Thaut


Re: geting stack trace from signal handlers

2013-06-07 Thread Timothee Cour
On Fri, Jun 7, 2013 at 12:39 AM, nazriel  wrote:

> On Thursday, 6 June 2013 at 21:50:58 UTC, Timothee Cour wrote:
>
>> Great!
>> two issues (on OSX at least):
>>
>> A)
>> it seems the top-most element of the call stack gets chopped off; eg in
>> your code, the main_module.main symbol will not appear in the stack trace.
>> Any idea why or how to fix that?
>> Is that some inlining issue ? I tried with dmd -g, or -gs or -gc.
>> This can be annoying when the top-most function is a large function and
>> it's not at all clear where the code stopped.
>>
>>  I haven't got Mac OSX to test it out but I fixed it a little bit so it
> is less hacky:
>
> http://dpaste.dzfl.pl/241c6fb5
>

Thanks, ya, the demangling part is the easy part :) (although demangle is
still incomplete in many cases...)



> Compiler switches you may want to consider are:
> -gc -L--export-dynamic -O0


export-dynamic or rdynamic are not available on OSX.
-gc doesn't change anything on dmd (and -O0 isn't available on dmd)
-gc -O0 doesn't change anything on ldc



>
>
>  B)
>> there are no line numbers. I did a complex workaround by launching a
>> process and calling atos to get those, but isn't there a better way?
>>
>>  Yeah, it is a complex issue. There are 2 ways to fix it from what I know.
> 1) pipe addresses to addr2line - easier
>

OSX doesn't have addr2line, hence my solution based on piping to atos on
OSX. It works except in a few cases where for some reason only the basename
of the file is shown instead of full file path, but its a bit complex so i
was hoping for simpler.



> 2) use libdwarf - more complex but also more out-of-box solution


Thanks for the link, that sounds promising! Will look at it.
under doc:
http://sourceforge.net/apps/trac/elftoolchain/wiki/libdwarf
relevant sections:
"Line Number Operations"


Conditional compilation

2013-06-07 Thread finalpatch

Hi folks,

I need to apply different calling conventions to the same 
interfaces when compiling for different platform. It's something 
like this:


OSX:

interface InterfaceA : IUnknown
{
extern(C):
...
}

Windows:

interface InterfaceA : IUnknown
{
...
}

I have to add extern(C) on OSX because apparently when the 
compiler sees IUnknown it automatically assumes the calling 
convention is extern(Windows) and in order to maintain 
compatibility with existing system I have to explicitly declare 
them as extern(C).


Now I have several dozens of interfaces like the above. I don't 
want to repeat them for OSX and Windows because the interface 
definitions are identical except the extern(C) line.


I have tried using version() like this:

interface InterfaceA : IUnknown {
version(OSX)
{
extern(C):
}
...methohds.
}

but it doesn't work because version limits the scope of the 
extern(C). static if has the same problem.


In C/C++ this is really easy, I can simply define a macro which 
expands to extern(C) on OSX and nothing on windows. Is there any 
way to achieve this in D without repeating the interface 
definitions?


Re: Conditional compilation

2013-06-07 Thread finalpatch

string mixins and template mixins don't work either.

On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:

Hi folks,

I need to apply different calling conventions to the same 
interfaces when compiling for different platform. It's 
something like this:


OSX:

interface InterfaceA : IUnknown
{
extern(C):
...
}

Windows:

interface InterfaceA : IUnknown
{
...
}

I have to add extern(C) on OSX because apparently when the 
compiler sees IUnknown it automatically assumes the calling 
convention is extern(Windows) and in order to maintain 
compatibility with existing system I have to explicitly declare 
them as extern(C).


Now I have several dozens of interfaces like the above. I don't 
want to repeat them for OSX and Windows because the interface 
definitions are identical except the extern(C) line.


I have tried using version() like this:

interface InterfaceA : IUnknown {
version(OSX)
{
extern(C):
}
...methohds.
}

but it doesn't work because version limits the scope of the 
extern(C). static if has the same problem.


In C/C++ this is really easy, I can simply define a macro which 
expands to extern(C) on OSX and nothing on windows. Is there 
any way to achieve this in D without repeating the interface 
definitions?




Emplace using private constructor

2013-06-07 Thread develop32
In a project I'm working on there are classes that are available 
publicly but I want to disable their construction outside of 
their modules.


class Display
{
   const string name;

   private this(string name)
   {
  this.name = name;
   }

   static Display[] all()
   {
  // Returns all available displays, the only place where 
Display objects

  // are to be constructed.
   }
}

This is easy when using "new". But I'm using std.conv.emplace 
which does not work with private constructors.


"Don't know how to initialize an object of type Display with 
arguments (string)"


Is there any solution to this problem? I know I can just make the 
constructor public but it just feels wrong, I want to keep public 
API as small as possible and it bugs me that language/library 
limits me here.


Re: Conditional compilation

2013-06-07 Thread Mike Parker

On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:

Hi folks,

I need to apply different calling conventions to the same 
interfaces when compiling for different platform.


extern(System)

On Windows, it will be seen by the compiler as extern(Windows), 
elsewhere as extern(C).


Re: Learning D

2013-06-07 Thread Daemon

Thanks for all the fantastic replies, now I'm really glad I asked.

Ali, I'm already reading your book and it's pretty good. I've 
also ordered The D Programming language, so that should be a big 
help. The only thing that remains is patience I guess. I won't 
give up on D so easily this time.


Thanks a lot, really


Re: Emplace using private constructor

2013-06-07 Thread develop32
Nevermind, problem was not worth the question. I just copied code 
from Phobos std.conv.emplace and placed it directly in my code, 
it works since it is in the same module as the private 
constructor.


Re: Emplace using private constructor

2013-06-07 Thread Ali Çehreli
tldr; I had the crazy idea of mixing-in a specialization of emplace but 
failed probably because mixin does not respect template constraints.


On 06/07/2013 06:50 AM, develop32 wrote:

> Nevermind, problem was not worth the question. I just copied code from
> Phobos std.conv.emplace and placed it directly in my code, it works
> since it is in the same module as the private constructor.

But it is too heavy-handed. Your problem exposes a real weakness. Other 
library code will make assumptions like emplace does below and they will 
fail if the constructor is not accessible. From std.conv.emplace:


// Call the ctor if any
static if (is(typeof(result.__ctor(args
{
// T defines a genuine constructor accepting args
// Go the classic route: write .init first, then call ctor
result.__ctor(args);
}

I tried making your code better but not copying emplace's implementation:

module display;

import std.conv;

class Display
{
private:
const string name;

this(string name)
{
this.name = name;
}

public:

static Display emplace(Args...)(void[] chunk, auto ref Args args)
{
return std.conv.emplace!(Display)(chunk, args);
}
}

Here is a test program:

import display;

void main()
{
enum roomNeeded = __traits(classInstanceSize, Display);
ubyte[roomNeeded] buffer;
auto d = Display.emplace(buffer, "hello");
}

But I failed with the same error:

Error: static assert  "Don't know how to initialize an object of type 
Display with arguments (string)"


Then I thought about mixing in the template but that did not work either:

class Display
{
// ...

static Display emplace(Args...)(void[] chunk, auto ref Args args)
{
mixin std.conv.emplace!(Display, string);
}
}

The error message indicated that mixin was picking the wrong 
specialization, because it had a template constraint for 'struct':


T* emplace(T, Args...)(T* chunk, auto ref Args args)
if (is(T == struct))
{
// ...
}

If it picked the one that matched is(T == class) then we would have 
achieved our goal without copy-pasting.


Still, if it worked, it also feels hacky because we would be mixing-in a 
specialization right inside our function and hope that it would somehow 
work in our environment. For example, the specialization of emplace has 
a return statement:


return result;

What if my function should not return? I guess then we would mix-in 
inside a wrapper function, call that function, and ignore the return value.


I have a feeling that bearophile already has a bug report about all of 
this but I haven't checked yet. :p


Not the same, but it look like it is related to this bug:

  http://d.puremagic.com/issues/show_bug.cgi?id=9235

Ali



Question on class templates

2013-06-07 Thread Eric


interface Identity(V, K)
{
}

class X(V, K) : Identity!(V, K)
{
private K k;

public this(K k) { this.k = k; }
}

void main()
{
auto x = new X!(X, double)(6.0);
}

Hi -

I have the code above, but the line in main() gives the following 
compile error:
Error: template instance X!(X, double) does not match template 
declaration X(V, K)


If I change the template parameter X to something else, like 
string, it compiles fine.  But I want the Identity interface to 
know the type of the implementing class.  Is that possible?


Thanks,

Eric





Re: Question on class templates

2013-06-07 Thread anonymous

On Friday, 7 June 2013 at 17:52:48 UTC, Eric wrote:


interface Identity(V, K)
{
}

class X(V, K) : Identity!(V, K)
{
private K k;

public this(K k) { this.k = k; }
}

void main()
{
auto x = new X!(X, double)(6.0);
}

Hi -

I have the code above, but the line in main() gives the 
following compile error:
Error: template instance X!(X, double) does not match template 
declaration X(V, K)


If I change the template parameter X to something else, like 
string, it compiles fine.  But I want the Identity interface to 
know the type of the implementing class.  Is that possible?


Thanks,

Eric


class X(K) : Identity!(X, K)

auto x = new X!(double)(6.0);


Re: Learning D

2013-06-07 Thread Gary Willoughby

On Friday, 7 June 2013 at 13:45:50 UTC, Daemon wrote:

The only thing that remains is patience I guess.


That, buy Andrei's book and ask questions here. :)

http://www.amazon.co.uk/The-Programming-Language-Andrei-Alexandrescu/dp/0321635361


Re: Question on class templates

2013-06-07 Thread Eric

On Friday, 7 June 2013 at 18:06:26 UTC, anonymous wrote:

On Friday, 7 June 2013 at 17:52:48 UTC, Eric wrote:


interface Identity(V, K)
{
}

class X(V, K) : Identity!(V, K)
{
   private K k;

   public this(K k) { this.k = k; }
}

void main()
{
   auto x = new X!(X, double)(6.0);
}

Hi -

I have the code above, but the line in main() gives the 
following compile error:
Error: template instance X!(X, double) does not match template 
declaration X(V, K)


If I change the template parameter X to something else, like 
string, it compiles fine.  But I want the Identity interface 
to know the type of the implementing class.  Is that possible?


Thanks,

Eric


class X(K) : Identity!(X, K)

auto x = new X!(double)(6.0);


Oh... Duh...  Thanks.


Strange output

2013-06-07 Thread Daemon
The following program is supposed to print out only numbers that 
are less than 5, yet the number 63 gets printed.


module main;

import std.stdio;
import std.conv;

int main(string[] argv)
{
	auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 16, 
27, 20, 2, -4, -17, 8, 64, 6]);


foreach (int b; de[0 .. $])
{
writeln(b);
}

readln();

return 0;
}

T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0]))
{
break;
}
}
return input;
}

I realize it's extremely improbable that I've discovered a bug, 
so what exactly could I be doing wrong? Why is the output:


2
-4
-17
8
63
6

I'm probably missing something obvious. If the input is just 
[63], then nothing gets printed out.


Re: Strange output

2013-06-07 Thread Daemon
auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 16, 
27, 20, 2, -4, -17, 8, 64, 6]);


Just a clarification, it prints out 64 with the input above, I 
changed it later just to test it and forgot to update the rest.




std.traits functions causing the compiler to crash

2013-06-07 Thread Eric

mport std.traits;

interface Xidentity(V, K) {
static if (hasMember!(V, "k")) static assert(0);
public int getInstanceCount();
}

class X(K) : Xidentity!(X!(K), K) {
private K k;

X newInstance(K k) { return(new X(k)); }

private this(K k) { this.k = k; }
public int getInstanceCount() { return(5); }
}

void main() {
auto x = new X!(double)(6.0);
}

If I compile the above code, the static if statement in the 
interface
declaration causes the compiler to segfault without any other 
information.

gdb give the following stacktrace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf75106c0 (LWP 30889)]
0x08170d26 in TraitsExp::semantic ()
Current language:  auto; currently asm
(gdb) backtrace
#0  0x08170d26 in TraitsExp::semantic ()
#1  0x0809a51a in Expression::ctfeSemantic ()
#2  0x081446da in TemplateInstance::semanticTiargs ()
#3  0x08145035 in TemplateInstance::semanticTiargs ()
#4  0x08148f04 in TemplateInstance::semantic ()
#5  0x08149470 in TemplateInstance::semantic ()
#6  0x0809feae in ScopeExp::semantic ()
#7  0x0809fcfd in BinExp::semantic ()
#8  0x080ac66e in BinExp::semanticp ()
#9  0x080ac7bc in EqualExp::semantic ()
#10 0x080aa75e in OrOrExp::semantic ()
#11 0x0809a51a in Expression::ctfeSemantic ()
#12 0x08077bee in VarDeclaration::semantic ()
#13 0x0804ccc5 in StaticIfDeclaration::semantic ()
#14 0x0813fc49 in TemplateInstance::expandMembers ()
#15 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#16 0x08148ce0 in TemplateInstance::semantic ()
#17 0x08149470 in TemplateInstance::semantic ()
#18 0x0809feae in ScopeExp::semantic ()
#19 0x0809a51a in Expression::ctfeSemantic ()
#20 0x080713c4 in StaticIfCondition::include ()
#21 0x0804b443 in ConditionalDeclaration::include ()
#22 0x0804cd40 in StaticIfDeclaration::include ()
#23 0x0804cc95 in StaticIfDeclaration::semantic ()
#24 0x0806a0f0 in InterfaceDeclaration::semantic ()
#25 0x0813fc49 in TemplateInstance::expandMembers ()
#26 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#27 0x08148ce0 in TemplateInstance::semantic ()
#28 0x08149470 in TemplateInstance::semantic ()
#29 0x080fcd13 in TypeInstance::resolve ()
#30 0x080f9a4d in TypeInstance::semantic ()
#31 0x080685b0 in ClassDeclaration::semantic ()
#32 0x0813fc49 in TemplateInstance::expandMembers ()
#33 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#34 0x08148ce0 in TemplateInstance::semantic ()
#35 0x08149470 in TemplateInstance::semantic ()
#36 0x080fcd13 in TypeInstance::resolve ()
#37 0x080f9a4d in TypeInstance::semantic ()
#38 0x080af314 in NewExp::semantic ()
#39 0x080deaf4 in ExpInitializer::inferType ()
#40 0x08077560 in VarDeclaration::semantic ()
#41 0x080a3ea1 in DeclarationExp::semantic ()
#42 0x0812cc41 in ExpStatement::semantic ()
#43 0x08138c91 in CompoundStatement::semantic ()
#44 0x080c0cf5 in FuncDeclaration::semantic3 ()
#45 0x080f16bb in Module::semantic3 ()
#46 0x080edf5c in tryMain ()
#47 0x080efab2 in main ()

I'm using compiler version v2.063-devel-53aa503.
Is this a known problem, or is there a work-around?

Thanks,

Eric


Re: Emplace using private constructor

2013-06-07 Thread develop32

On Friday, 7 June 2013 at 16:14:25 UTC, Ali Çehreli wrote:
But it is too heavy-handed. Your problem exposes a real 
weakness. Other...


Well, its not *that* heavy.

// Inside Display class.
auto display = alloc!Display;
display.__ctor(name);

Where alloc(T) is a bigger part of the original emplace code and 
is widely used.


But generally, yeah. It would be nice to fix mixins.





Re: Strange output

2013-06-07 Thread develop32

On Friday, 7 June 2013 at 19:10:54 UTC, Daemon wrote:
The following program is supposed to print out only numbers 
that are less than 5, yet the number 63 gets printed.


module main;

import std.stdio;
import std.conv;

int main(string[] argv)
{
	auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 
16, 27, 20, 2, -4, -17, 8, 64, 6]);


foreach (int b; de[0 .. $])
{
writeln(b);
}

readln();

return 0;
}

T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0]))
{
break;
}
}
return input;
}

I realize it's extremely improbable that I've discovered a bug, 
so what exactly could I be doing wrong? Why is the output:


2
-4
-17
8
63
6

I'm probably missing something obvious. If the input is just 
[63], then nothing gets printed out.


It looks like your find function just stops at the first item 
that is less than five (which is two) and returns a range 
consisting of all the following items.
If you'll look closer, your output is just all items after and 
including 2.




Re: Strange output

2013-06-07 Thread Daemon

On Friday, 7 June 2013 at 19:47:39 UTC, develop32 wrote:

On Friday, 7 June 2013 at 19:10:54 UTC, Daemon wrote:
The following program is supposed to print out only numbers 
that are less than 5, yet the number 63 gets printed.


module main;

import std.stdio;
import std.conv;

int main(string[] argv)
{
	auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 
16, 27, 20, 2, -4, -17, 8, 64, 6]);


foreach (int b; de[0 .. $])
{
writeln(b);
}

readln();

   return 0;
}

T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0]))
{
break;
}
}
return input;
}

I realize it's extremely improbable that I've discovered a 
bug, so what exactly could I be doing wrong? Why is the output:


2
-4
-17
8
63
6

I'm probably missing something obvious. If the input is just 
[63], then nothing gets printed out.


It looks like your find function just stops at the first item 
that is less than five (which is two) and returns a range 
consisting of all the following items.
If you'll look closer, your output is just all items after and 
including 2.


I totally misunderstood the for loop before, I feel ashamed. 
Thanks a lot, haha


Re: Strange output

2013-06-07 Thread H. S. Teoh
On Fri, Jun 07, 2013 at 09:10:53PM +0200, Daemon wrote:
> The following program is supposed to print out only numbers that are
> less than 5, yet the number 63 gets printed.

On Fri, Jun 07, 2013 at 09:14:00PM +0200, Daemon wrote:
> >auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 16,
> >27, 20, 2, -4, -17, 8, 64, 6]);
> 
> Just a clarification, it prints out 64 with the input above, I
> changed it later just to test it and forgot to update the rest.

This should not be surprising. Please see my comments below:


> module main;
> 
> import std.stdio;
> import std.conv;
> 
> int main(string[] argv)
> {
>   auto de = find!(delegate(a) { return a < 5; })([10, 11, 15, 16, 27,
> 20, 2, -4, -17, 8, 64, 6]);
> 

OK, so here 'de' is assigned whatever is returned by 'find', and the
following loop prints out its contents. The question then is, what does
find() return?


>   foreach (int b; de[0 .. $])
>   {
>   writeln(b);
>   }
>   
>   readln();
> 
> return 0;
> }
> 
> T[] find(alias pred, T)(T[] input)
>   if (is(typeof(pred(input[0])) == bool))
> {
>   for (; input.length > 0; input = input[1 .. $])

OK, so what the above is saying, is that you want to loop over the input
array, and reduce it by one element each time (i.e. slice from 1 to the
end). So let's look at the input main() is giving it: [10, 11, 15, ...].
So the first time round, we're looking at the entire array, which starts
with the element 10.


>   {
>   if (pred(input[0]))
>   {
>   break;
>   }

So here, 'pred' is passed the value of input[0]. The first time round,
input[0] is 10, so pred returns false: because 10 < 5 is false. So the
loop runs again, and the next time round, the array has been shortened
to [11, 15, ...]. So now, input[0] is 11, and again, 11 < 5 is false, so
the loop keeps running.

Now what happens after the next few iterations, when you get to '2'? At
that point, input looks like this: [2, -4, -17, 8, 64, 6]. So input[0]
is 2, and since 2 < 5, pred(input[0]) returns true. So the next line
says 'break', which means "stop running the loop". Remember that at this
point, input is [2, -4, -17, 8, 64, 6]. And then finally:


>   }
>   return input;
> }

This says, return input (which is currently [2, -4, -17, 8, 64, 6]). So
going back to main(), we see that 'de' must be [2, -4, -17, 8, 64, 6].
And indeed, that's the output you get.

So the program isn't doing anything wrong. It's just that what you wrote
isn't quite what you wanted. :)

It sounds like you wanted to *filter* the array for elements less than
5. So what you need to do is, once you find an element that's 5 or
greater, you need to skip over it. However, a D array is a *contiguous*
list of elements; there's no such thing as a skipped element in an
array. So you can't just return a slice of the original array -- a slice
is also a contiguous block of elements; while it *can* give you a
"sub-array" view of the original array, it cannot start somewhere, skip
over some elements, and then continue.

The easiest solution is to construct a new array that doesn't have the
offending elements, maybe something along these lines:

T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
// Note this line: we're creating a new array containing only
// the elements we want.
T[] result;

for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0]))
{
// Found an element that satisfies our
// predicate, so append that to the end of our
// results.
result ~= input[0];

// (No break here: we want to look at every
// element in the input.)
}
}

// N.B.: instead of returning input, which is a slice of the
// original array, we return the new array we've constructed
// that only has the elements we want.
return result;
}

Hope this helps!


T

-- 
Freedom of speech: the whole world has no right *not* to hear my spouting off!


Re: std.traits functions causing the compiler to crash

2013-06-07 Thread bearophile

Eric:


Is this a known problem, or is there a work-around?


This is your code reduced a little:

import std.traits: hasMember;
interface Xidentity(V, K) if (!hasMember!(V, "x")) {
}
class Foo(K): Xidentity!(Foo!K, K) {
K x;
}
void main() {
new Foo!double;
}


I think it contains a loop at the level of types. In theory the 
compiler should catch them and give a nice error message.


You probably want to use the template constraint syntax, as I 
have used.


In D return is not a function, so don't use the ( ).

Bye,
bearophile


-profile

2013-06-07 Thread Anthony Goins

Compiling with -profile and without -release
Gives the following error (not exactly but the best I can recall)
balancedParens is not nothrow  safe pure

With -release and -profile all is fine.
Builds fine without -profile.

Simple question is why?


opEquals does not work?

2013-06-07 Thread Namespace

Did I miss something?

I expected this output

opEquals: 23 == 23
Equal 1
opEquals: 23 == 23
Equal 2

by the following code, but I only get this:

opEquals: 23 == 23
Equal 2


Code:
[code]
import std.stdio;

class A {
public:
int id;

this(int id) {
this.id = id;
}

bool opEquals(const A a) const {
writefln("opEquals: %d == %d", this.id, a.id);
return a.id == this.id;
}
}

void main() {
A a1 = new A(23);
A a2 = new A(23);

if (a1 == a2) {
writeln("Equal 1");
}

if (a1.opEquals(a2)) {
writeln("Equal 2");
}
}
[/code]


Re: opEquals does not work?

2013-06-07 Thread Namespace
I got it. I must use Object instead of A... How ridiculous. I 
thought this was already fixed...


Re: -profile

2013-06-07 Thread bearophile

Anthony Goins:


Simple question is why?


Looks like a little compiler bug. Please create a minimal example 
that shows the problem. If it's a real problem then it's for 
Bugzilla.


Bye,
bearophile


Re: opEquals does not work?

2013-06-07 Thread w0rp

On Friday, 7 June 2013 at 20:51:13 UTC, Namespace wrote:
I got it. I must use Object instead of A... How ridiculous. I 
thought this was already fixed...


The class opEquals is quite like .equals in Java. You need to 
match the signature of Object, which is implicitly the base class 
of all classes. I think I recommend something like this.


override bool opEquals(Object o) const {
auto other = cast(A) o;

// It's probably easy to miss out !is null here, which 
matters.

return other !is null && this.id == other.id;
}


Re: opEquals does not work?

2013-06-07 Thread Namespace

On Friday, 7 June 2013 at 20:58:40 UTC, w0rp wrote:

On Friday, 7 June 2013 at 20:51:13 UTC, Namespace wrote:
I got it. I must use Object instead of A... How ridiculous. I 
thought this was already fixed...


The class opEquals is quite like .equals in Java. You need to 
match the signature of Object, which is implicitly the base 
class of all classes. I think I recommend something like this.


override bool opEquals(Object o) const {
auto other = cast(A) o;

// It's probably easy to miss out !is null here, which 
matters.

return other !is null && this.id == other.id;
}


Yes, I remember. As I heard it the first time I thought it's 
because of the limited compiler and that it will fixed some day.


Re: opEquals does not work?

2013-06-07 Thread w0rp

On Friday, 7 June 2013 at 21:02:15 UTC, Namespace wrote:


Yes, I remember. As I heard it the first time I thought it's 
because of the limited compiler and that it will fixed some day.


opEquals for classes is interesting because you actually do need 
to write 'Object' there because of type polymorphism.


Re: opEquals does not work?

2013-06-07 Thread Jonathan M Davis
On Friday, June 07, 2013 22:51:12 Namespace wrote:
> I got it. I must use Object instead of A... How ridiculous. I
> thought this was already fixed...

I have an open pull request as part of the move to getting rid of opEquals, 
opCmp, toHash, and toString from Object, and it would make it so that you 
could use something other than Object:

https://github.com/D-Programming-Language/druntime/pull/459

However, due to D's overload rules, you will _always_ be forced to have an 
opEquals which takes the most base class that you can compare. But you should 
be able to do something like overload it with the derived class type and then 
alias the base classes' opEquals into the scope of the derived class.

- Jonathan M Davis


Re: -profile

2013-06-07 Thread bearophile

Anthony Goins:


Simple question is why?


I am compiling this code with -profile, and I don't see errors:


import std.string: balancedParens;
void main() {
assert(balancedParens("[[]]", '[', ']'));
}


Bye,
bearophile


Re: opEquals does not work?

2013-06-07 Thread w0rp

On Friday, 7 June 2013 at 21:18:12 UTC, Jonathan M Davis wrote:


I have an open pull request as part of the move to getting rid 
of opEquals,
opCmp, toHash, and toString from Object, and it would make it 
so that you

could use something other than Object


Oh, that's cool. I didn't know about that.


Re: opEquals does not work?

2013-06-07 Thread bearophile

Jonathan M Davis:

However, due to D's overload rules, you will _always_ be forced 
to have an

opEquals which takes the most base class that you can compare.


http://d.puremagic.com/issues/show_bug.cgi?id=10292

Bye,
bearophile


Re: opEquals does not work?

2013-06-07 Thread Namespace

On Friday, 7 June 2013 at 21:42:36 UTC, bearophile wrote:

Jonathan M Davis:

However, due to D's overload rules, you will _always_ be 
forced to have an

opEquals which takes the most base class that you can compare.


http://d.puremagic.com/issues/show_bug.cgi?id=10292

Bye,
bearophile


Thank you.


Re: opEquals does not work?

2013-06-07 Thread Ali Çehreli

On 06/07/2013 02:18 PM, Jonathan M Davis wrote:

> I have an open pull request as part of the move to getting rid of 
opEquals,

> opCmp, toHash, and toString from Object, and it would make it so that you
> could use something other than Object:

I hope it supports delegate-taking toString overload for classes.[1]

Ali

[1] As a reminder to others who don't know or keep forgetting like me, 
:) toString has a more efficient toString overload. Unfortunately, it 
works only with structs at this point.


I am way off-topic now but here is an example:

import std.stdio;
import std.format;

struct Point
{
int x;
int y;

void toString(void delegate(const(char)[]) sink) const
{
formattedWrite(sink, "(%s,%s)", x, y);
}
}

struct Color
{
ubyte r;
ubyte g;
ubyte b;

void toString(void delegate(const(char)[]) sink) const
{
formattedWrite(sink, "RGB:%s,%s,%s", r, g, b);
}
}

struct ColoredPoint
{
Color color;
Point point;

void toString(void delegate(const(char)[]) sink) const
{
formattedWrite(sink, "{%s;%s}", color, point);
}
}

struct Poligon
{
ColoredPoint[] points;

this(ColoredPoint[] points)
{
this.points = points;
}

void toString(void delegate(const(char)[]) sink) const
{
formattedWrite(sink, "%s", points);
}
}

void main()
{
auto poligon = Poligon(
[ ColoredPoint(Color(10, 10, 10), Point(1, 1)),
  ColoredPoint(Color(20, 20, 20), Point(2, 2)),
  ColoredPoint(Color(30, 30, 30), Point(3, 3)) ]);

writeln(poligon);
}

The advantage of this method over the more-common toString() overload 
(the one that returns string) is that although there are still a total 
of 10 calls made to various toString() functions, those calls 
collectively produce a single string, not 10.


Ali



Re: Strange output

2013-06-07 Thread Jesse Phillips

On Friday, 7 June 2013 at 19:10:54 UTC, Daemon wrote:
The following program is supposed to print out only numbers 
that are less than 5, yet the number 63 gets printed.


You're probably just playing around, but FYI the function is

http://dlang.org/phobos/std_algorithm.html#filter

While you've created the same find already in std.algorithm.


Re: -profile

2013-06-07 Thread Anthony Goins

On Friday, 7 June 2013 at 21:39:26 UTC, bearophile wrote:

Anthony Goins:


Simple question is why?


I am compiling this code with -profile, and I don't see errors:


import std.string: balancedParens;
void main() {
assert(balancedParens("[[]]", '[', ']'));
}


Bye,
bearophile


okay found it

module profiletest;
import std.path;

void main()
{
assert(globMatch("foo.bar", "*"));
}

dmd -profile profiletest.d
/usr/include/dmd/phobos/std/path.d(2187): Error: balancedParens 
is not nothrow
/usr/include/dmd/phobos/std/path.d(2188): Error: balancedParens 
is not nothrow



globMatch is @safe pure nothrow
balancedParens is not nothrow
-release ignores contracts, right?



Re: -profile

2013-06-07 Thread Anthony Goins

On Friday, 7 June 2013 at 23:42:58 UTC, Anthony Goins wrote:

On Friday, 7 June 2013 at 21:39:26 UTC, bearophile wrote:

Anthony Goins:


Simple question is why?


I am compiling this code with -profile, and I don't see errors:


import std.string: balancedParens;
void main() {
   assert(balancedParens("[[]]", '[', ']'));
}


Bye,
bearophile


okay found it

module profiletest;
import std.path;

void main()
{
assert(globMatch("foo.bar", "*"));
}

dmd -profile profiletest.d
/usr/include/dmd/phobos/std/path.d(2187): Error: balancedParens 
is not nothrow
/usr/include/dmd/phobos/std/path.d(2188): Error: balancedParens 
is not nothrow



globMatch is @safe pure nothrow
balancedParens is not nothrow
-release ignores contracts, right?

 oops forgot to say
balancedParens is called from the 'in' contract of globMatch.
Is this even worth a bug report?


Re: -profile

2013-06-07 Thread bearophile

Anthony Goins:


Is this even worth a bug report?


Yes, it's worth a bug report in Bugzilla, it's a (small) Phobos 
Bug. I confirmed its presence.


Bye,
bearophile


Re: opEquals does not work?

2013-06-07 Thread Jonathan M Davis
On Friday, June 07, 2013 14:53:44 Ali Çehreli wrote:
> On 06/07/2013 02:18 PM, Jonathan M Davis wrote:
> > I have an open pull request as part of the move to getting rid of
> 
> opEquals,
> 
> > opCmp, toHash, and toString from Object, and it would make it so that you
> 
> > could use something other than Object:
> I hope it supports delegate-taking toString overload for classes.[1]

It should be perfectly possible to declare such an overload now. It just won't 
work when used through Object. If it doesn't work, then I expect that that's a 
bug in formattedWrite and friends.

As far as overriding goes though, that'll depend on what the base classes of a 
class have declared. If they all declare toString without a delegate, then 
that's what you'd have to override to use toString using references of their 
type, whereas if they use the toString which takes a delegate, then that's 
what you'd have to override. But I don't see any reason that you can't have 
both just so long as the type of the reference that you're using has it.

Howver, I supposed that a potential problem with formattedWrite and friends 
is that if you have two toString methods, it has to pick which one to use, and 
right now, it probably just picks the one from Object. Better behavior would 
be to us the delegate one if it's there and fall back to the non-delegate 
version if it's not. Long term though, formattedWrite et al will probably have 
the potential of not working at all with a class if we fully remove it from 
Object ike we intend to, since then there's no guarantee that a class or any 
of its base classes have even declared any toString.

In any case, if toString with a delegate doesn't work with formattedWrite et 
al, then we need an enhancement request for that to be fixed.

- Jonathan M Davis


Derelict linking (Debian + derelict + dmd 2.062)

2013-06-07 Thread mimi

Hi!

I am trying to add SDL support to my project. libderelict-dev 
installed into my Debian and I am just added "import 
derelict.sdl2.sdl;". And caused:


dmd -I/usr/include/dmd/ -unittest -g -debug -debug=osmpbf 
-L-lDerelictUtil -L-lDerelictSDL2 -L-ldl  -ofmain libosmpbfd.a 
math/rtree2d.d math/geometry.d math/graph.d pb_encoding.d main.d
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.data+0x60): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader7__ClassZ'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x41f0): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader4loadMFZv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x41f8): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader4loadMFAyaZv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4200): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader4loadMFAAyaZv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4208): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader6unloadMFZv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4210): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader8isLoadedMFNdZb'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4220): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader10loadSymbolMFAyaZPv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4228): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader3libMFNdZS8derelict4util9sharedlib9SharedLib'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o):(.rodata+0x4230): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader8bindFuncMFPPvAyabZv'
/usr/lib/x86_64-linux-gnu/libDerelictSDL2.a(sdl_1_698.o): In 
function 
`_D8derelict4sdl23sdl18DerelictSDL2Loader6__ctorMFZC8derelict4sdl23sdl18DerelictSDL2Loader':
../derelict/sdl2/sdl.d:(.text._D8derelict4sdl23sdl18DerelictSDL2Loader6__ctorMFZC8derelict4sdl23sdl18DerelictSDL2Loader+0x1b): 
undefined reference to 
`_D8derelict4util6loader15SharedLibLoader6__ctorMFAyaZC8derelict4util6loader15SharedLibLoader'

collect2: error: ld returned 1 exit status
--- errorlevel 1
make: *** [main] Error 1

What is it? Can anyone help?


Re: -profile

2013-06-07 Thread Anthony Goins

On Friday, 7 June 2013 at 23:57:37 UTC, bearophile wrote:

Anthony Goins:


Is this even worth a bug report?


Yes, it's worth a bug report in Bugzilla, it's a (small) Phobos 
Bug. I confirmed its presence.


Bye,
bearophile


Thank you for all your help. Not just here but throughout the 
forums.

One more question though...

What is the error here :)
1. dmd profiletest.d
   should fail because balancedParens is not nothrow
   even though it is called from a contract.

2. dmd -profile profiletest.d
  should succeed because nothrow, @safe, pure don't apply to 
contracts


Re: -profile

2013-06-07 Thread bearophile

Anthony Goins:


Is this even worth a bug report?


http://d.puremagic.com/issues/show_bug.cgi?id=10295

Bye,
bearophile


Re: -profile

2013-06-07 Thread bearophile

Anthony Goins:


What is the error here :)
1. dmd profiletest.d
   should fail because balancedParens is not nothrow
   even though it is called from a contract.

2. dmd -profile profiletest.d
  should succeed because nothrow, @safe, pure don't apply to 
contracts


I think -profile and pre-conditions should not be correlated. 
That's why I have reported this bug as a dmd bug instead just of 
a Phobos bug.
I am not sure what's the right answer. I think the right answer 
is 1.


Bye,
bearophile


Re: std.traits functions causing the compiler to crash

2013-06-07 Thread Eric

O

import std.traits: hasMember;
interface Xidentity(V, K) if (!hasMember!(V, "x")) {
}
class Foo(K): Xidentity!(Foo!K, K) {
K x;
}
void main() {
new Foo!double;
}


I think it contains a loop at the level of types. In theory the 
compiler should catch them and give a nice error message.


You probably want to use the template constraint syntax, as I 
have used.


Yes, the template constraint is much better.  However, the 
compiler

still crashes, even with the new code:

import std.traits: hasMember;

interface Identity(V, K) if (!hasMember!(V, "k")) {
}

class Foo(K): Identity!(Foo!K, K) {
K k;
}

void main() {
new Foo!double;
}

(dmd7) mrbig:~/tp/d_test2/dlib>dmd Test.d
Segmentation fault (core dumped)



In D return is not a function, so don't use the ( ).

Yeah, I know.  return returns an expression, and parenthesis
are legal expression syntax:)
-Eric



Re: std.traits functions causing the compiler to crash

2013-06-07 Thread bearophile

Eric:

Yes, the template constraint is much better.  However, the 
compiler still crashes, even with the new code:


Because there's a type definition loop, regardless. Using a 
constraint doesn't change that situation.


Bye,
bearophile


Re: Conditional compilation

2013-06-07 Thread Anthony Goins

On Friday, 7 June 2013 at 12:20:23 UTC, finalpatch wrote:

string mixins and template mixins don't work either.

On Friday, 7 June 2013 at 12:14:45 UTC, finalpatch wrote:

Hi folks,

I need to apply different calling conventions to the same 
interfaces when compiling for different platform. It's 
something like this:


OSX:

interface InterfaceA : IUnknown
{
extern(C):
   ...
}

Windows:

interface InterfaceA : IUnknown
{
   ...
}

I have to add extern(C) on OSX because apparently when the 
compiler sees IUnknown it automatically assumes the calling 
convention is extern(Windows) and in order to maintain 
compatibility with existing system I have to explicitly 
declare them as extern(C).


Now I have several dozens of interfaces like the above. I 
don't want to repeat them for OSX and Windows because the 
interface definitions are identical except the extern(C) line.


I have tried using version() like this:

interface InterfaceA : IUnknown {
   version(OSX)
   {
   extern(C):
   }
   ...methohds.
}

but it doesn't work because version limits the scope of the 
extern(C). static if has the same problem.


In C/C++ this is really easy, I can simply define a macro 
which expands to extern(C) on OSX and nothing on windows. Is 
there any way to achieve this in D without repeating the 
interface definitions?


string mixin will work

import std.stdio;
enum :string
{
 //define relevant functions in this string
 x1 =
 `void testfunc(string str)
 {
  writeln(str);
 }`
}


version(X)
{
 extern(C) mixin(x1);
 string str2 = "c version";
}

version(Y)
{
 extern(Windows) mixin(x1);
 string str2 = "windows version";
}

void main()
{
 testfunc(str2);
}

Yes it's ... well ... not very ... umm
But it works :)
extern(system) MIGHT be a better option.


Re: Derelict linking (Debian + derelict + dmd 2.062)

2013-06-07 Thread Mike Parker

On Saturday, 8 June 2013 at 00:27:36 UTC, mimi wrote:

Hi!

I am trying to add SDL support to my project. libderelict-dev 
installed into my Debian and I am just added "import 
derelict.sdl2.sdl;". And caused:


dmd -I/usr/include/dmd/ -unittest -g -debug -debug=osmpbf 
-L-lDerelictUtil -L-lDerelictSDL2 -L-ldl  -ofmain libosmpbfd.a


Looks like a problem with the order in which the libraries are 
specified on the command line. Swap them like so: 
"-L-lDerelictSDL2 -L-lDerelictUtil" and see if that does it for 
you.


Re: Derelict linking (Debian + derelict + dmd 2.062)

2013-06-07 Thread mimi

Thanks! It worked!

On Saturday, 8 June 2013 at 03:44:22 UTC, Mike Parker wrote:

On Saturday, 8 June 2013 at 00:27:36 UTC, mimi wrote:

Hi!

I am trying to add SDL support to my project. libderelict-dev 
installed into my Debian and I am just added "import 
derelict.sdl2.sdl;". And caused:


dmd -I/usr/include/dmd/ -unittest -g -debug -debug=osmpbf 
-L-lDerelictUtil -L-lDerelictSDL2 -L-ldl  -ofmain libosmpbfd.a


Looks like a problem with the order in which the libraries are 
specified on the command line. Swap them like so: 
"-L-lDerelictSDL2 -L-lDerelictUtil" and see if that does it for 
you.


Re: std.traits functions causing the compiler to crash

2013-06-07 Thread Eric

On Saturday, 8 June 2013 at 02:32:57 UTC, bearophile wrote:

Eric:

Yes, the template constraint is much better.  However, the 
compiler still crashes, even with the new code:


Because there's a type definition loop, regardless. Using a 
constraint doesn't change that situation.


Bye,
bearophile


How is there a type definition loop?  I'm just trying to constrain
the interface.  At a minimum this should be a compiler bug, but
I would hope that dimple constraints would work.

-Eric


can we detect at compile time module ctor/dtor cycles ?

2013-06-07 Thread Timothee Cour
Why can't we detect at compile time module ctor/dtor cycles (instead of
runtime) ?
See example below.

It should be easy to detect the chain at CT:

algo:
build graph from import dependencies a=>b if module a imports module b.
mark as red the modules that have a ctor
collapse each non-red node into its parent (and update parent's edges)
detect cycles (eg BFS)

(same with dtor)



a1:
import a2;
void main(){}
static this(){}


a2:
import a3;
static this(){}

a3:
import a1;


rdmd --force --build-only -oftest a1 #works
./test #error:
object.Exception@src/rt/minfo.d(243): Aborting: Cycle detected between
modules with ctors/dtors:
a1 -> a2 -> a3 -> a1


Re: can we detect at compile time module ctor/dtor cycles ?

2013-06-07 Thread Jonathan M Davis
On Friday, June 07, 2013 23:23:25 Timothee Cour wrote:
> Why can't we detect at compile time module ctor/dtor cycles (instead of
> runtime) ?

At minimum, separate compilation stops it. A .di file isn't likely to have them 
even if its corresponding .d file did. IIRC, there were other reasons as well, 
but I don't remember them at the moment.

- Jonathan M Davis