Re: Multiple assignment

2011-02-26 Thread spir

On 02/26/2011 01:56 AM, bearophile wrote:

Is this program showing a bug in multiple assignments (DMD 2.052)?


void main() {
 int i;
 int[2] x;
 i, x[i] = 1;
 assert(x == [1, 0]); // OK

 int j;
 int[2] y;
 y[j], j = 1;
 assert(y == [0, 0]); // Not OK
}


At the end of the program I expect y to be [1,0] instead of [0,0].


I'm far to be a C expert, but that looks like very normal C semantics, ain't 
it? with all its stupidity, indeed...

I would enjoy an error in both cases. (not enough rvalues)

Denis
--
_
vita es estrany
spir.wikidot.com



Re: Multiple assignment

2011-02-26 Thread spir

On 02/26/2011 04:26 AM, Steven Schveighoffer wrote:

Let me fix that for you:

func(j++, y[j])


That should be illegal: a statement used as expression, but keeping it's effect 
anyway, and not the least kind of, namely an assignment, meaning a change of 
the program state.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Multiple assignment

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 00:51:45 spir wrote:
 On 02/26/2011 04:26 AM, Steven Schveighoffer wrote:
  Let me fix that for you:
  
  func(j++, y[j])
 
 That should be illegal: a statement used as expression, but keeping it's
 effect anyway, and not the least kind of, namely an assignment, meaning a
 change of the program state.

Umm. There is no statement used as an expression here. The only statement is a 
function call. Both j++ and y[j] are expressions. Even the function call is an 
expression. It's just that if it's followed by a semi-colon, it becomes a 
statement.

Regardless, the best solution is to make the order of evaluation of the 
function 
arguments fixed at left-to-right instead of undefined. And as I understand it, 
Walter intends to make D do that at some point. It's just that he hasn't gotten 
around to it yet.

- Jonathan M Davis


Icons

2011-02-26 Thread Joel Christensen
I noticed in windows with D you can use .res (eg. dmd main.d smile.res) 
files for icons any way. but how do you make icon .res files?


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at 
http://www.digitalmars.com/d/2.0/htomodule.html


But when it comes to long in C you have to be careful. On 32bit 
platforms a C long will be 32bit long. But on 64bit platforms it 
depends of what data model is used. To simplify things:


* On Windows 64bit a C long will be 32bit long
* On Posix 64bit a C long will be 64bit long.

What you can do is to create an alias called c_long and c_ulong, 
something like this:


version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models: 
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models


--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 02:35, Jonathan M Davis wrote:

On Friday, February 25, 2011 17:16:31 simendsjo wrote:

On 26.02.2011 02:06, bearophile wrote:

simendsjo:

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In D the size of int/uint is 32 bits and long/ulong is 64 bits.

In C the size of int, unsigned int, long, long long int, unsigned long
long int, etc are not fixed, the change according to the CPU.
sizeof(int)= sizeof(long)= sizeof(long long).

A help:
http://www.digitalmars.com/d/2.0/phobos/std_stdint.html

Bye,
bearophile


Ouch.. Any tips on porting C code that would work nicely with a
transition to 64 bit?
Should I change all long and int to int_atleast_32_t and long long to 64?


It depends entirely on what the code is doing. It could be completely safe to
convert all ints, longs, and long longs to long to long. Or you may have to
choose int or long depending on what system the code is supposed to be for.

In many cases, using a larger type wouldn't matter, since it can hold more than
the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is
irrelevant. In other cases, the type needs to be an exact size, because the code
is doing bit shifts or whatnot (in which case they _should_ have been using
int32_t and int64_t on Linux and whatever the equivalent is on Windows, but
unfortunately, many programmers don't). And if you're dealing with a struct,
it's possible that that struct has to be an exact size (e.g. for some binary
format), and using the wrong type in converting could make it the wrong size.

If you want to know what the appropriate D type is for the C/C++ code, you
_need_ to know what it does.  Now, IIRC, int is almost guaranteed to be 32 bits
at this point, and long long is essentially guaranteed to be 64 bits, but long
varies from system to system - both in terms of OS and architecture. IIRC, long
is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in
x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long
long, then it's probably reasonably safe to use int for int and long for long
long, but it's ultimately system dependent. Personally, I would argue that C/C++
code should use int when you don't care about the size of an integral type and
use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the
size, but there's no guarantee that programmers are going to be that disciplined
about it.


A C long is 64bit long on Solaris 64bit according to this: 
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



In any case, if you really don't know the code and don't want to take the time
to understand it, I'd use int for int, long for long long, and then if they have
long, I'd do the research to figure out which OS and architecture the code is
supposed to be for and use int if long long is 32 bits and long if it's 64 bits.
If you don't know what system it was built for, then I'd probably just use long
and hoped that they weren't doing anything that made using an integral type
which was too large a problem.

- Jonathan M Davis



--
/Jacob Carlborg


Re: std.xml empty element

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 07:20, Tom wrote:

El 25/02/2011 20:07, Jacob Carlborg escribió:

On 2011-02-25 21:11, Tom wrote:

El 24/02/2011 19:40, Tom escribió:

El 24/02/2011 09:51, Jacob Carlborg escribió:

On 2011-02-24 06:48, Tom wrote:

Hi, how can I create an empty element with current D2 std.xml Element
implementation?

stdout.writeln(new Element(foo)); // Shields foo/foo instead of
foo /

Thanks in advance,
Tom;


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



I see :(
Thanks...


Lucky me, 2.052 solves this bug and doesn't break anything.

Tom;


Really? Which changeset?



Not sure what you mean, but it seems it got fixed when 4069 was resolved...
http://d.puremagic.com/issues/show_bug.cgi?id=4069

Tom;


Ok, thanks. I was referring to the actual code change that fixed the 
problem, which would be: 
https://github.com/D-Programming-Language/phobos/commit/b3ad939cf41adfefd33b16d2d91ca56d568cddac


--
/Jacob Carlborg


Problem with std.regex: *+? not allowed in atom

2011-02-26 Thread Jacob Carlborg
I'm trying to use the std.regex module but when I run my application I 
get an exception. The exception message says:


*+? not allowed in atom

The code I have is:

import std.regex;

void main ()
{
regex(`\.(?=(?:[^\]*\[^\]*\)*(?![^\]*\))`, m);
}

I'm compiling this with DMD 2.052 on Mac OS X.

Full stack trace:


5   test0x2356 void 
std.regex.Regex!(char).Regex.error(immutable(char)[]) + 126
6   test0x7c1d int 
std.regex.Regex!(char).Regex.parseAtom!(const(immutable(char)[])).parseAtom(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 237
7   test0x772d int 
std.regex.Regex!(char).Regex.parsePiece!(const(immutable(char)[])).parsePiece(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 117
8   test0x76b3 int 
std.regex.Regex!(char).Regex.parseRegex!(const(immutable(char)[])).parseRegex(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 431
9   test0x7c88 int 
std.regex.Regex!(char).Regex.parseAtom!(const(immutable(char)[])).parseAtom(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 344
10  test0x772d int 
std.regex.Regex!(char).Regex.parsePiece!(const(immutable(char)[])).parsePiece(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 117
11  test0x74ff int 
std.regex.Regex!(char).Regex.parseRegex!(immutable(char)[]).parseRegex(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 431
12  test0x72f2 void 
std.regex.Regex!(char).Regex.compile!(immutable(char)[]).compile(immutable(char)[], 
immutable(char)[]) + 370
13  test0x7176 ref 
std.regex.Regex!(char).Regex 
std.regex.Regex!(char).Regex.__ctor!(immutable(char)[]).__ctor(immutable(char)[], 
immutable(char)[]) + 26
14  test0x21f7 
std.regex.Regex!(char).Regex 
std.regex.regex!(immutable(char)[]).regex(immutable(char)[], 
immutable(char)[]) + 187

15  test0x2138 _Dmain + 44
16  test0x0001b213 extern (C) int 
rt.dmain2.main(int, char**).void runMain() + 23
17  test0x0001b19a extern (C) int 
rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 38
18  test0x0001b25b extern (C) int 
rt.dmain2.main(int, char**).void runAll() + 59
19  test0x0001b19a extern (C) int 
rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 38

20  test0x0001b12b main + 179
21  test0x2101 start + 53

--
/Jacob Carlborg


Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Magnus Lie Hetland

On 2011-02-26 01:20:49 +0100, Jonathan M Davis said:


So, using such assertions makes good sense when you control
both the caller and the callee and it's something that should never happen.


Yeah, in my case that's what's going on. I'll only be using the 
contracts during testing anyway, and remove them with -release in the 
code that's actually to be used. (The code is part of some benchmarking 
experiments, so I'd rather not have any kind of checking like that when 
running those.)



However, if you don't necessarily control the caller or if it's something that
_could_ happen at runtime (even if it shouldn't), then an exception makes a lot
more sense.


OK. I had the impression that using assert() in contracts was standard, 
also for API functions. I thought contracts fulfilled a similar sort of 
function to assert(), in that they're removed in release code -- as 
opposed to enforce(), for example...? I'm guessing that if I released a 
binary version of a library, I wouldn't leave the contracts in? Or 
perhaps I would (but, as you say, with exceptions)? Depends on the 
situation, perhaps?


What kind of exceptions would be most relevant to indicate a contract 
failure (if the contracts are made part of the API)?



I tend to view exceptions as part of the API and think that they should be
tested. Assertions, on the other hand, aren't really part of the API, 
since they

go away in release mode, and I therefore view them as test code. They're
verifying that your logic is correct.


Exactly. The same, of course, applies to contracts -- which is why I'm 
a bit confused by your suggestion to use exceptions in them.


Or perhaps I'm misreading you completely, and you're only suggesting 
that I use code paths that throw exceptions in the function body 
itself, e.g., with enforce(foo, exception) (which would make sense to 
me)?



So, on some level, it is indeed a stylistic thing, but where you choose to use
exceptions and where you choose to use assertions can have a big effect on code
that uses your code.


Sure thing. It just seems to me that contracts and assertions go well 
together, and have the same function, of testing your program logic?


I guess the driving force of my original query was the old first, see 
your test fail idea of test-driven programming. If I just slap a 
precondition on some code, it won't fail because things aren't 
implemented properly yet (as a normal unit test would) -- I'd actively 
have to implement a call to it *improperly*. It just seemed naturally 
to me to do that as part of the test code, rather than a one-off thing 
in the main code.


However, I could always add a call to my unit test, run it, and see it 
crash -- and then comment it out. Doesn't seem like the prettiest way 
to handle things, but it's OK, I guess together with the idea of making 
the contracts super-simple (and to test any functionality they use 
separately).


[snip]

I guess the conclusion will be that I'll focus on keeping my
preconditions really simple. (And any utility functions I use in them
can then get unit tests of their own instead ;)

That's probably a good way to handle it .


OK, good :)

--
Magnus Lie Hetland
http://hetland.org



Re: Problem with std.regex: *+? not allowed in atom

2011-02-26 Thread Dmitry Olshansky

On 26.02.2011 14:10, Jacob Carlborg wrote:
I'm trying to use the std.regex module but when I run my application I 
get an exception. The exception message says:


*+? not allowed in atom

The code I have is:

import std.regex;

void main ()
{
regex(`\.(?=(?:[^\]*\[^\]*\)*(?![^\]*\))`, m);
}


Well the thing is, std.regex is not quite ECMA complaint (as vaguely 
stated in docs). To the best of my knowledge not a single one variant of 
the forms (?:...) ... (?=...) is supported . Also see 
http://d.puremagic.com/issues/show_bug.cgi?id=5169, you may try out my 
patch there to support (?:...). It's a slightly outdated, but std.regex  
wasn't in very active development.




I'm compiling this with DMD 2.052 on Mac OS X.

Full stack trace:


5   test0x2356 void 
std.regex.Regex!(char).Regex.error(immutable(char)[]) + 126
6   test0x7c1d int 
std.regex.Regex!(char).Regex.parseAtom!(const(immutable(char)[])).parseAtom(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 237
7   test0x772d int 
std.regex.Regex!(char).Regex.parsePiece!(const(immutable(char)[])).parsePiece(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 117
8   test0x76b3 int 
std.regex.Regex!(char).Regex.parseRegex!(const(immutable(char)[])).parseRegex(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 431
9   test0x7c88 int 
std.regex.Regex!(char).Regex.parseAtom!(const(immutable(char)[])).parseAtom(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 344
10  test0x772d int 
std.regex.Regex!(char).Regex.parsePiece!(const(immutable(char)[])).parsePiece(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 117
11  test0x74ff int 
std.regex.Regex!(char).Regex.parseRegex!(immutable(char)[]).parseRegex(const(immutable(char)[]), 
ref uint, std.outbuffer.OutBuffer) + 431
12  test0x72f2 void 
std.regex.Regex!(char).Regex.compile!(immutable(char)[]).compile(immutable(char)[], 
immutable(char)[]) + 370
13  test0x7176 ref 
std.regex.Regex!(char).Regex 
std.regex.Regex!(char).Regex.__ctor!(immutable(char)[]).__ctor(immutable(char)[], 
immutable(char)[]) + 26
14  test0x21f7 
std.regex.Regex!(char).Regex 
std.regex.regex!(immutable(char)[]).regex(immutable(char)[], 
immutable(char)[]) + 187

15  test0x2138 _Dmain + 44
16  test0x0001b213 extern (C) int 
rt.dmain2.main(int, char**).void runMain() + 23
17  test0x0001b19a extern (C) int 
rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 38
18  test0x0001b25b extern (C) int 
rt.dmain2.main(int, char**).void runAll() + 59
19  test0x0001b19a extern (C) int 
rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 38

20  test0x0001b12b main + 179
21  test0x2101 start + 53




--
Dmitry Olshansky



Re: Icons

2011-02-26 Thread J Chapman
== Quote from Joel Christensen (joel...@gmail.com)'s article
 I noticed in windows with D you can use .res (eg. dmd main.d smile.res)
 files for icons any way. but how do you make icon .res files?

With a resource compiler. Digital Mars supplies one as part of its C++
utilities package: http://ftp.digitalmars.com/bup.zip.

Documentation is here: http://www.digitalmars.com/ctg/rcc.html


Re: Problem with std.regex: *+? not allowed in atom

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 12:29, Dmitry Olshansky wrote:

On 26.02.2011 14:10, Jacob Carlborg wrote:

I'm trying to use the std.regex module but when I run my application I
get an exception. The exception message says:

*+? not allowed in atom

The code I have is:

import std.regex;

void main ()
{
regex(`\.(?=(?:[^\]*\[^\]*\)*(?![^\]*\))`, m);
}


Well the thing is, std.regex is not quite ECMA complaint (as vaguely
stated in docs). To the best of my knowledge not a single one variant of
the forms (?:...) ... (?=...) is supported . Also see
http://d.puremagic.com/issues/show_bug.cgi?id=5169, you may try out my
patch there to support (?:...). It's a slightly outdated, but std.regex
wasn't in very active development.


Ok thanks. I'll try the patch.

--
/Jacob Carlborg


Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 03:24:15 Magnus Lie Hetland wrote:
 On 2011-02-26 01:20:49 +0100, Jonathan M Davis said:
  So, using such assertions makes good sense when you control
  both the caller and the callee and it's something that should never
  happen.
 
 Yeah, in my case that's what's going on. I'll only be using the
 contracts during testing anyway, and remove them with -release in the
 code that's actually to be used. (The code is part of some benchmarking
 experiments, so I'd rather not have any kind of checking like that when
 running those.)
 
  However, if you don't necessarily control the caller or if it's something
  that _could_ happen at runtime (even if it shouldn't), then an exception
  makes a lot more sense.
 
 OK. I had the impression that using assert() in contracts was standard,
 also for API functions. I thought contracts fulfilled a similar sort of
 function to assert(), in that they're removed in release code -- as
 opposed to enforce(), for example...? I'm guessing that if I released a
 binary version of a library, I wouldn't leave the contracts in? Or
 perhaps I would (but, as you say, with exceptions)? Depends on the
 situation, perhaps?
 
 What kind of exceptions would be most relevant to indicate a contract
 failure (if the contracts are made part of the API)?

Well, the biggest problem with using assertions to verify input to a function 
is 
that if you distribute your code as a library, odds are it will be in release 
mode, and then there won't be any assertions in it. In that case, I believe 
that 
template functions will still end up with the assertions in it when the user of 
your library compiles with assertions enabled, since template code is not 
generated until it's instantiated, but none of the other assertions will work. 
So, assertions for public APIs really don't work very well. On top of that, 
even 
if assertions _are_ enabled (either because it's a templated function or 
they're 
actually using a non-release version of your library), then an assertion 
failure 
makes it look like _your_ code is wrong rather than theirs.

Regardless, if you're using an assertion, what you're doing is requiring that 
the input meet some sort of pre-conditions and you're testing that the caller's 
code to verify that it meets those conditions. If you use an exception, then 
it's perfectly legitimate for a caller to give input which violates your pre-
conditions, but then the caller has to deal with it. In some cases, you 
actually 
_need_ to do it that way simply because the input could reasonably be invalid 
at 
runtime, and which point it _needs_ to be checked at runtime and have the error 
reported without killing the program - which means that you need an exception.

Personally, I only ever use assertions for pre-conditions if I'm controlling 
both the caller and the callee and I really expect that they will _never_ fail. 
It's test code plain and simple. In pretty much all of the cases, I use 
exceptions. Assertions are purely for catching logic errors in code.

Now, if you're throwing an exception from a function due to a pre-condition 
failure, then the type that you throw depends entirely on what you're doing. In 
Phobos, it tends to depend on what module it's in. std.datetime throws 
DateTimeExceptions. std.file throws FileExceptions. In other cases, it's more 
specific. e.g. std.typecons.conv throws ConvExceptions. What type of Exception 
a 
function throws is entirely up to you. It could be a plain old Exception if 
that's what you want. It's just that if it's a specific type of Exception than 
code can catch that specific type and handle it differently than it might 
handle a 
generic Exception.

  I tend to view exceptions as part of the API and think that they should
  be tested. Assertions, on the other hand, aren't really part of the API,
  since they
  go away in release mode, and I therefore view them as test code. They're
  verifying that your logic is correct.
 
 Exactly. The same, of course, applies to contracts -- which is why I'm
 a bit confused by your suggestion to use exceptions in them.
 
 Or perhaps I'm misreading you completely, and you're only suggesting
 that I use code paths that throw exceptions in the function body
 itself, e.g., with enforce(foo, exception) (which would make sense to
 me)?

Never throw exceptions form in, out, or invariant blocks. They'll just go away 
in release mode. Only use assertions in there. So, if you're going to throw an 
Exception, throw it from the function body or from some other function that 
gets 
called by that function.

Regardless of that, however, assertions should only be used when testing the 
internal logic of your program. If code from other libraries or any other code 
which you wouldn't be looking to test calls your function, then don't use an 
assertion to verify pre-conditions. If you're using assertions, you're testing 
that the caller is correct. You're verifying that the caller is not violating 

Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread spir

On 02/26/2011 12:24 PM, Magnus Lie Hetland wrote:

However, I could always add a call to my unit test, run it, and see it crash --
and then comment it out. Doesn't seem like the prettiest way to handle things,
but it's OK, I guess together with the idea of making the contracts
super-simple (and to test any functionality they use separately).


With named unittests, you could also have one of them check failure cases, and 
just comment out its call.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread David Nadlinger

On 2/26/11 1:15 PM, Jonathan M Davis wrote:

[…]  And from a perfectly practical standpoint, as soon as your code ends
up in a library, assertions are generally useless anyway,[…]


I don't quite think asserts are useless in libraries. If you need to 
care about performance in a library, you hit cases quite frequently 
where sanity-checking the input would be too expensive to be done in 
release mode, and thus you can't specify behavior on invalid input as 
part of your API using exceptions. Nevertheless, it is still useful to 
people using your library to get notified when they are messing 
something up as early as possible in debug mode, which is precisely what 
asserts are made for, at least in my opinion.


You can find this use of asserts in many libraries out there, LLVM being 
the first example that comes to my mind.


David



Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Magnus Lie Hetland

On 2011-02-26 13:15:58 +0100, Jonathan M Davis said:


On Saturday 26 February 2011 03:24:15 Magnus Lie Hetland wrote:

OK. I had the impression that using assert() in contracts was standard,
also for API functions. I thought contracts fulfilled a similar sort of
function to assert(), in that they're removed in release code -- as
opposed to enforce(), for example...? I'm guessing that if I released a
binary version of a library, I wouldn't leave the contracts in? Or
perhaps I would (but, as you say, with exceptions)? Depends on the
situation, perhaps?

What kind of exceptions would be most relevant to indicate a contract
failure (if the contracts are made part of the API)?


Well, the biggest problem with using assertions to verify input to a 
function is

that if you distribute your code as a library, odds are it will be in release
mode, and then there won't be any assertions in it.


[snip lots of stuff]

After reading your response, I first made lots of comments, but it's 
all a bit redundant. My summary is:


- You're (at times) talking about preconditions as a general concept, 
and that for public APIs, they should be enforced using exceptions.
- I've only been talking about the *language feature* of preconditions, 
i.e., in-clauses.
- We're both clear on that preconditions and asserts disappear in 
release mode, and that the two belong together, as part of your test 
scaffolding (and not as part of your public API).


Sound about right?

[snip]

Regardless of that, however, assertions should only be used when testing the
internal logic of your program. If code from other libraries or any other code
which you wouldn't be looking to test calls your function, then don't use an
assertion to verify pre-conditions. If you're using assertions, you're testing
that the caller is correct. You're verifying that the caller is not violating
your contract, but you're _not_ guaranteeing that the function will 
fail if they

violate the contract (since assertions can go away).


A very clarifying way of putting it, indeed.

As for my testing the test code intention, I guess (as I said) I 
actually *did* want to test the test. Not, perhaps, that it was correct 
(as discussed, it should be really simple), but to see it fail at least 
once -- a basic principle of test-driven programming. But I'll find 
other ways of doing that -- for example deliberately making the 
precondition slightly wrong at first :)


The test for the contract  is therefore _not_ part of the API. With 
Exceptions it _is_.


Right.

So, what it really comes down to is whether you looking to test the 
code which calls your function and are therefore willing to have that 
code give you bad input and let your function process it anyway (when 
assertions aren't compiled in) and you therefore use assertions, _or_ 
you're looking to guarantee that your function does _not_ continue if 
the contract is violated, and you want to _always_ error out - in which 
case you use Exceptions.


Yep. All in all, a very useful clarification for me.

As a side note: Why isn't there a release-version of the contract 
mechanisms? I would've thought that contracts would be even more useful 
between different programmers, than just between you and yourself...?-)


That is, wouldn't the same kind of mechanism be useful for *exactly* 
the kind of exception-based input checking that you're describing as 
the alternative to contracts+asserts?


I mean, the reason to remove preconditions and asserts is primarily 
performance and not semantics (although it certainly affects semantics, 
as you've pointed out)? We have enforce() as the alternative to 
assert(); why no alternative to in/out and invariants?


[snip]

And if you're using unit tests to test those, you're testing test code.


Sure. I've already accepted this :)

[snip]
Still, if you start testing test code, at what point does it make sense 
to stop?


Hm. Maybe I should write a test that tests itself?-)

More seriously: your points are well taken.

I still have a vague feeling that in-clauses are a bit different from 
out-closes, invariants and plain unit tests when it comes to the fail 
first approach to test-driven programming. A precondition won't fail 
because your code isn't yet functional -- it will only fail if you've 
actively written *wrong* code. But I guess that's just how it is :)



Complicated tests of _any_ kind are a bit dangerous.

[snip]

Hm. True.

Thanks for lots of useful input!

(Still curious about the hypothetical public API contract 
functionality, though, and why it's non-existent.)


--
Magnus Lie Hetland
http://hetland.org



Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Magnus Lie Hetland

On 2011-02-26 15:20:19 +0100, David Nadlinger said:


On 2/26/11 1:15 PM, Jonathan M Davis wrote:

[...]  And from a perfectly practical standpoint, as soon as your code ends
up in a library, assertions are generally useless anyway,[...]


I don't quite think asserts are useless in libraries. If you need to 
care about performance in a library, you hit cases quite frequently 
where sanity-checking the input would be too expensive to be done in 
release mode, and thus you can't specify behavior on invalid input as 
part of your API using exceptions. Nevertheless, it is still useful to 
people using your library to get notified when they are messing 
something up as early as possible in debug mode, which is precisely 
what asserts are made for, at least in my opinion.


But that would only work if they had access to the source, or a version 
not compiled in release mode, right?


Hmm.

This is also related to what Jonathan said about programming by 
contract -- and only using in-clauses (for example) when you also 
control the calling code. I guess what you're saying could be an 
argument in the other direction: that even though they certainly 
shouldn't be considered part of the public API (beyond documenting what 
would be input causing undefined behavior), they *could* be useful in a 
library that a client could use in debug mode, because it gives them 
some extra tests for their own code, for free. They can test that 
their own code is using your code correctly.


That sounds quite in line with programming by contract to me ... but 
then, again, I'm a reall n00b on the subject :)


--
Magnus Lie Hetland
http://hetland.org



Is std.cover deprecated or gone?

2011-02-26 Thread Magnus Lie Hetland

It's documented here...

 http://www.digitalmars.com/d/2.0/phobos/std_cover.html

... but I can't find it in the Phobos source. (Also, I can't import it 
-- which is perhaps the most pressing issue :)


It's just that I'm using rdmd (for convenience), but then I don't know 
where any coverage reports end up (unless I examine the path to the 
generated executable), so I thought I'd specify where I wanted them...


--
Magnus Lie Hetland
http://hetland.org



Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Mike Wey

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to long in C you have to be careful. On 32bit
platforms a C long will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C long will be 32bit long
* On Posix 64bit a C long will be 64bit long.

What you can do is to create an alias called c_long and c_ulong,
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and c_ulong.

--
Mike Wey


Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread David Nadlinger

On 2/26/11 4:08 PM, Magnus Lie Hetland wrote:

On 2011-02-26 15:20:19 +0100, David Nadlinger said:


On 2/26/11 1:15 PM, Jonathan M Davis wrote:

[...] And from a perfectly practical standpoint, as soon as your code
ends
up in a library, assertions are generally useless anyway,[...]


I don't quite think asserts are useless in libraries. If you need to
care about performance in a library, you hit cases quite frequently
where sanity-checking the input would be too expensive to be done in
release mode, and thus you can't specify behavior on invalid input as
part of your API using exceptions. Nevertheless, it is still useful to
people using your library to get notified when they are messing
something up as early as possible in debug mode, which is precisely
what asserts are made for, at least in my opinion.


But that would only work if they had access to the source, or a version
not compiled in release mode, right?


True, but as shipping debug libraries and headers is precisely what SDKs 
are for, I don't see much of a problem there. Heck, even Microsoft's C 
Runtime comes with an extra debug version…


David


Re: Problem with std.regex: *+? not allowed in atom

2011-02-26 Thread Jacob Carlborg

On 2011-02-26 12:29, Dmitry Olshansky wrote:

On 26.02.2011 14:10, Jacob Carlborg wrote:

I'm trying to use the std.regex module but when I run my application I
get an exception. The exception message says:

*+? not allowed in atom

The code I have is:

import std.regex;

void main ()
{
regex(`\.(?=(?:[^\]*\[^\]*\)*(?![^\]*\))`, m);
}


Well the thing is, std.regex is not quite ECMA complaint (as vaguely
stated in docs). To the best of my knowledge not a single one variant of
the forms (?:...) ... (?=...) is supported . Also see
http://d.puremagic.com/issues/show_bug.cgi?id=5169, you may try out my
patch there to support (?:...). It's a slightly outdated, but std.regex
wasn't in very active development.


I tried the patch but with no success. I still get the same error.

--
/Jacob Carlborg


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread simendsjo

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to long in C you have to be careful. On 32bit
platforms a C long will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C long will be 32bit long
* On Posix 64bit a C long will be 64bit long.

What you can do is to create an alias called c_long and c_ulong,
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



Re: Are function pointers compile time constants?

2011-02-26 Thread Dan Olson
d coder dlang.co...@gmail.com writes:

 Greetings

 I tried to initialize a struct member with a function pointer, and
 found that DMD2 did not like it. Are not function pointers compile
 time constants? And why they should not be?

 Regards
 - Cherry

I just want to point out that this *should* be doable in D.  At compile
time the function's address in the object code is a placeholder that the
linker or loader will fixup based on the function symbol.  This is what
linkers do!  And if an function ptr is used, the function can still be
inlined; just need to keep around the real function reference through
the pointer.

Dan


Re: Is std.cover deprecated or gone?

2011-02-26 Thread Magnus Lie Hetland

On 2011-02-26 16:30:10 +0100, Magnus Lie Hetland said:


It's documented here...

  http://www.digitalmars.com/d/2.0/phobos/std_cover.html

... but I can't find it in the Phobos source. (Also, I can't import it 
-- which is perhaps the most pressing issue :)


It's just that I'm using rdmd (for convenience), but then I don't know 
where any coverage reports end up (unless I examine the path to the 
generated executable), so I thought I'd specify where I wanted them...


Seems the specific problem isn't really a problem -- rdmd with -conv 
places the files in the right directory anyway :)


--
Magnus Lie Hetland
http://hetland.org



Re: Problem with std.regex: *+? not allowed in atom

2011-02-26 Thread Dmitry Olshansky

On 26.02.2011 19:52, Jacob Carlborg wrote:

On 2011-02-26 12:29, Dmitry Olshansky wrote:

On 26.02.2011 14:10, Jacob Carlborg wrote:

I'm trying to use the std.regex module but when I run my application I
get an exception. The exception message says:

*+? not allowed in atom

The code I have is:

import std.regex;

void main ()
{
regex(`\.(?=(?:[^\]*\[^\]*\)*(?![^\]*\))`, m);
}


Well the thing is, std.regex is not quite ECMA complaint (as vaguely
stated in docs). To the best of my knowledge not a single one variant of
the forms (?:...) ... (?=...) is supported . Also see
http://d.puremagic.com/issues/show_bug.cgi?id=5169, you may try out my
patch there to support (?:...). It's a slightly outdated, but std.regex
wasn't in very active development.


I tried the patch but with no success. I still get the same error.

The patch fixes only (?: ) form and not the lookahead and others. Sorry, 
it was the only one I needed back then.
I'll  check if I can make a patch for them as well when I have some 
spare time. That's would be around monday if, of course,  nobody else 
wishes to rush into the depths of std.regex.


--
Dmitry Olshansky



Re: Multiple assignment

2011-02-26 Thread Dan Olson
Jonathan M Davis jmdavisp...@gmx.com writes:

 On Friday, February 25, 2011 17:31:36 Ali Çehreli wrote:
 On 02/25/2011 05:09 PM, bearophile wrote:
int j;
int[2] y;
y[j] = j = 1;
 
 I think that's undefined behavior in C and C++. It is not defined
 whether j's previous or past value is used in y[j].
 
 I would expect the situation be the same in D.

 No, that should be perfectly defined. What's undefined is when you do
 something like func(j, y[j]). The evaluation order of the function
 arguments is undefined.  However, the evaluation order when dealing
 with an assignment should be defined.  I _could_ be wrong about that,
 but there's no question that the assignments themselves are guaranteed
 to be done in right-to-left order.

 - Jonathan M Davis

Java made assignment well defined by saying:
  First evaluate the left-hand-side to determine a variable to assign to.
  Then evaluate the right-hand-side for the value.

If the right-hand-side is another assignment, repeat...

So given:
int i = 0;
int[] a = new int[4];

a[i++] = a[i+=2] = i = 9;

You are can depend on getting:

i = 9
a = [9, 0, 0, 9]


D today on windows yields the same output.  Will the D language spec
make this the define behavior too?  I noticed that
http://www.digitalmars.com/d/2.0/expression.html currently says it is
implementation defined.  The example given is:

i = i++;

None of this is stuff you'd normally want to write unless entering an
obfuscated programming contest, but Java's rules say if i = 42, 'i' will end up
still being 42.

Dan


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Mike Wey

On 02/26/2011 05:58 PM, simendsjo wrote:

On 26.02.2011 17:06, Mike Wey wrote:

On 02/26/2011 11:49 AM, Jacob Carlborg wrote:

On 2011-02-26 01:28, simendsjo wrote:

C is not my strong side, so I'm having some problems wrapping some
code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long
doesn't
exist in 64 bit?


In general you can follow the table at
http://www.digitalmars.com/d/2.0/htomodule.html

But when it comes to long in C you have to be careful. On 32bit
platforms a C long will be 32bit long. But on 64bit platforms it
depends of what data model is used. To simplify things:

* On Windows 64bit a C long will be 32bit long
* On Posix 64bit a C long will be 64bit long.

What you can do is to create an alias called c_long and c_ulong,
something like this:

version (D_LP64)
{
version (Windows)
{
alias int c_long;
alias uint c_ulong;
}

else
{
alias long c_long;
alias ulong c_ulong;
}
}

else
{
alias int c_long;
alias uint c_ulong;
}

To read more about data models:
http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models



You can also import core.stdc.config witch defines both c_long and
c_ulong.


Thanks for all the answers. Is something like this correct?

version(X86_64)
{
version(Windows)
{
version = LLP64;
}
else version(Posix)
{
version = LP64;
}
else
{
static assert(0);
}

version(LLP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(LP64)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(ILP64)
{
alias short c_short;
alias ushort c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else version(SILP64)
{
alias long c_short;
alias ulong c_ushort;
alias long c_int;
alias ulong c_uint;
alias long c_long;
alias ulong c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias ulong c_size_t;
}
else
{
static assert(0);
}
}
else version(X86)
{
alias short c_short;
alias ushort c_ushort;
alias int c_int;
alias uint c_uint;
alias int c_long;
alias uint c_ulong;
alias long c_longlong;
alias ulong c_ulonglong;
alias uint c_size_t;
}
else
{
static assert(0);
}



The aliases look correct, but i don't think you'll need ILP64 or SILP64 
any time soon.


--
Mike Wey


Re: Icons

2011-02-26 Thread Joel Christensen

On 27-Feb-11 12:56 AM, J Chapman wrote:

== Quote from Joel Christensen (joel...@gmail.com)'s article

I noticed in windows with D you can use .res (eg. dmd main.d smile.res)
files for icons any way. but how do you make icon .res files?


With a resource compiler. Digital Mars supplies one as part of its C++
utilities package: http://ftp.digitalmars.com/bup.zip.

Documentation is here: http://www.digitalmars.com/ctg/rcc.html


Thanks Chapman. :-)


Initializing a class pointer

2011-02-26 Thread Tyro[a.c.edwards]

class Class{}

void main()
{
Class myClass;
Class* pClass0 = myClass;  // OK

Class* pClass1 = new Class; // Error: cannot implicitly convert [8]
// expression (new Class) of type t.Class
// to test.Class*

Class* pClass2 = (new Class);
// Error: new Class is not an lvalue[12]

Class mClass = (new Class);// Error: cannot implicitly convert [14]
// expression (new Class) of type Class*
// to test.Class
}

C++ uses the process on line [8] above to initialize a class pointer. 
Obviously it does not work in D. But given the error message at [14], I 
thought [12] would have been allowed. What is the proper way to convert 
[8] to D?


Thanks


Re: Icons

2011-02-26 Thread Joel Christensen

On 27-Feb-11 11:24 AM, Joel Christensen wrote:

On 27-Feb-11 12:56 AM, J Chapman wrote:

== Quote from Joel Christensen (joel...@gmail.com)'s article

I noticed in windows with D you can use .res (eg. dmd main.d smile.res)
files for icons any way. but how do you make icon .res files?


With a resource compiler. Digital Mars supplies one as part of its C++
utilities package: http://ftp.digitalmars.com/bup.zip.

Documentation is here: http://www.digitalmars.com/ctg/rcc.html




Hmm. Can't seem to get it to work.


Re: Initializing a class pointer

2011-02-26 Thread Simen kjaeraas

Tyro[a.c.edwards] nos...@home.com wrote:


class Class{}

void main()
{
Class myClass;
Class* pClass0 = myClass;  // OK

Class* pClass1 = new Class; // Error: cannot implicitly convert [8]
 // expression (new Class) of type t.Class
 // to test.Class*

Class* pClass2 = (new Class);
 // Error: new Class is not an lvalue[12]

Class mClass = (new Class);// Error: cannot implicitly convert [14]
// expression (new Class) of type Class*
// to test.Class
}

C++ uses the process on line [8] above to initialize a class pointer.  
Obviously it does not work in D. But given the error message at [14], I  
thought [12] would have been allowed. What is the proper way to convert  
[8] to D?


Classes in D are already references (like Class in C++), thus line [8]
would be a pointer to a reference to a class, something which may make
some kind of sense, but is unlikely to be what you want.

Perhaps this question is better answered if you explain why you want a
pointer to a class?


--
Simen


Re: Initializing a class pointer

2011-02-26 Thread Tyro[a.c.edwards]

On 2/27/2011 8:10 AM, Simen kjaeraas wrote:

Tyro[a.c.edwards] nos...@home.com wrote:


class Class{}

void main()
{
Class myClass;
Class* pClass0 = myClass; // OK

Class* pClass1 = new Class; // Error: cannot implicitly convert [8]
// expression (new Class) of type t.Class
// to test.Class*

Class* pClass2 = (new Class);
// Error: new Class is not an lvalue [12]

Class mClass = (new Class);// Error: cannot implicitly convert [14]
// expression (new Class) of type Class*
// to test.Class
}

C++ uses the process on line [8] above to initialize a class pointer.
Obviously it does not work in D. But given the error message at [14],
I thought [12] would have been allowed. What is the proper way to
convert [8] to D?


Classes in D are already references (like Class in C++), thus line [8]
would be a pointer to a reference to a class, something which may make
some kind of sense, but is unlikely to be what you want.

Perhaps this question is better answered if you explain why you want a
pointer to a class?




I'm trying to convert some c++ code that defines

T func(par...)
{   
  Controller * pCtrl = WinGetLongController * (hwnd);
  .
  .
  .
  switch(msg)
  {
  case FirstMatch:
 pCtrl = new Controller (hwnd, reinterpret_castCREATESTRUCT * 
(lParam));

 break;
  }
}

I'm not sure why I need a pointer to the class, just trying to figure it 
out.


Re: Initializing a class pointer

2011-02-26 Thread Simen kjaeraas

Tyro[a.c.edwards] nos...@home.com wrote:


I'm trying to convert some c++ code that defines

T func(par...)
{   
   Controller * pCtrl = WinGetLongController * (hwnd);
   .
   .
   .
   switch(msg)
   {
   case FirstMatch:
  pCtrl = new Controller (hwnd, reinterpret_castCREATESTRUCT *  
(lParam));

  break;
   }
}

I'm not sure why I need a pointer to the class, just trying to figure it  
out.


Ah. You would not need a pointer to the class in D. Instead, your function
would look something like this:

T funct(par...)
{
auto pCtrl = WinGetLong!Controller(hwnd);
...
switch(msg)
{
case FirstMatch:
pCtrl = new Controller(hWnd, cast(CREATESTRUCT*)lParam);
break;
}
}

C++ classes are in some ways more akin to D structs, in that:

class A {};

void foo(){
A bar;
}

bar would be allocated on the stack in C++, while in D bar would be a
pointer to a class instance on the heap. (well, it would be null, but
when you set it to something, that something would reside on the heap)

--
Simen


Re: Initializing a class pointer

2011-02-26 Thread Tyro[a.c.edwards]

On 2/27/2011 8:52 AM, Simen kjaeraas wrote:

Tyro[a.c.edwards] nos...@home.com wrote:


I'm trying to convert some c++ code that defines

T func(par...)
{
Controller * pCtrl = WinGetLongController * (hwnd);
.
.
.
switch(msg)
{
case FirstMatch:
pCtrl = new Controller (hwnd, reinterpret_castCREATESTRUCT * (lParam));
break;
}
}

I'm not sure why I need a pointer to the class, just trying to figure
it out.


Ah. You would not need a pointer to the class in D. Instead, your function
would look something like this:

T funct(par...)
{
auto pCtrl = WinGetLong!Controller(hwnd);
...
switch(msg)
{
case FirstMatch:
pCtrl = new Controller(hWnd, cast(CREATESTRUCT*)lParam);
break;
}
}

C++ classes are in some ways more akin to D structs, in that:

class A {};

void foo(){
A bar;
}

bar would be allocated on the stack in C++, while in D bar would be a
pointer to a class instance on the heap. (well, it would be null, but
when you set it to something, that something would reside on the heap)



Ok, that's essentially what I have, except that I used Controller pCtrl 
vice auto. WinGetLong however, is a template that calls 
GetWindowLongPtrA() and casts it's result (in this case) to Controller. 
 GetWindowLongPtrA() returns LONG_PTR (aka int) and therefore fails 
miserably on the cast attempt. On the reverse, there is a WinSetLong 
that attempts to cast Controller to int for use with 
SetWindowLongPtrA(). Neither of these functions complain when I use 
Controller* but I end up with the problem of trying to initialize a 
pointer with a reference to Controller.


Re: Multiple assignment

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 11:18:20 Dan Olson wrote:
 Jonathan M Davis jmdavisp...@gmx.com writes:
  On Friday, February 25, 2011 17:31:36 Ali Çehreli wrote:
  On 02/25/2011 05:09 PM, bearophile wrote:
 int j;
 int[2] y;
 y[j] = j = 1;
  
  I think that's undefined behavior in C and C++. It is not defined
  whether j's previous or past value is used in y[j].
  
  I would expect the situation be the same in D.
  
  No, that should be perfectly defined. What's undefined is when you do
  something like func(j, y[j]). The evaluation order of the function
  arguments is undefined.  However, the evaluation order when dealing
  with an assignment should be defined.  I _could_ be wrong about that,
  but there's no question that the assignments themselves are guaranteed
  to be done in right-to-left order.
  
  - Jonathan M Davis
 
 Java made assignment well defined by saying:
   First evaluate the left-hand-side to determine a variable to assign to.
   Then evaluate the right-hand-side for the value.
 
 If the right-hand-side is another assignment, repeat...
 
 So given:
 int i = 0;
 int[] a = new int[4];
 
 a[i++] = a[i+=2] = i = 9;
 
 You are can depend on getting:
 
 i = 9
 a = [9, 0, 0, 9]
 
 
 D today on windows yields the same output.  Will the D language spec
 make this the define behavior too?  I noticed that
 http://www.digitalmars.com/d/2.0/expression.html currently says it is
 implementation defined.  The example given is:
 
 i = i++;
 
 None of this is stuff you'd normally want to write unless entering an
 obfuscated programming contest, but Java's rules say if i = 42, 'i' will
 end up still being 42.

The assignment order is well-defined in both C++ an D, but the order of 
evaluation of the expressions is not. Now, Walter has stated in the past that 
he 
intends to make the order of evaluation of expressions defined in D at some 
point, but he hasn't done it yet, so right now it's still undefined.

Regardless, it doesn't really hurt you any to avoid ambiguous expressions like 
these and since there _are_ languages which leave ther evaluation order as 
undefined, it's probably a good habit to get into to _not_ write such ambiguous 
expressions.

- Jonathan M Davis


Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 07:03:29 Magnus Lie Hetland wrote:
 On 2011-02-26 13:15:58 +0100, Jonathan M Davis said:
  On Saturday 26 February 2011 03:24:15 Magnus Lie Hetland wrote:
  OK. I had the impression that using assert() in contracts was standard,
  also for API functions. I thought contracts fulfilled a similar sort of
  function to assert(), in that they're removed in release code -- as
  opposed to enforce(), for example...? I'm guessing that if I released a
  binary version of a library, I wouldn't leave the contracts in? Or
  perhaps I would (but, as you say, with exceptions)? Depends on the
  situation, perhaps?
  
  What kind of exceptions would be most relevant to indicate a contract
  failure (if the contracts are made part of the API)?
  
  Well, the biggest problem with using assertions to verify input to a
  function is
  that if you distribute your code as a library, odds are it will be in
  release mode, and then there won't be any assertions in it.
 
 [snip lots of stuff]
 
 After reading your response, I first made lots of comments, but it's
 all a bit redundant. My summary is:
 
 - You're (at times) talking about preconditions as a general concept,
 and that for public APIs, they should be enforced using exceptions.
 - I've only been talking about the *language feature* of preconditions,
 i.e., in-clauses.
 - We're both clear on that preconditions and asserts disappear in
 release mode, and that the two belong together, as part of your test
 scaffolding (and not as part of your public API).
 
 Sound about right?

Yeah.

 [snip]
 
  Regardless of that, however, assertions should only be used when testing
  the internal logic of your program. If code from other libraries or any
  other code which you wouldn't be looking to test calls your function,
  then don't use an assertion to verify pre-conditions. If you're using
  assertions, you're testing that the caller is correct. You're verifying
  that the caller is not violating your contract, but you're _not_
  guaranteeing that the function will fail if they
  violate the contract (since assertions can go away).
 
 A very clarifying way of putting it, indeed.
 
 As for my testing the test code intention, I guess (as I said) I
 actually *did* want to test the test. Not, perhaps, that it was correct
 (as discussed, it should be really simple), but to see it fail at least
 once -- a basic principle of test-driven programming. But I'll find
 other ways of doing that -- for example deliberately making the
 precondition slightly wrong at first :)

  The test for the contract  is therefore _not_ part of the API. With
  Exceptions it _is_.
 
 Right.

If you really want to test the test code, then test the test code. But even in 
test driven development, you _wouldn't_ be testing that the function fails when 
given values which violate its pre-conditions. That is _undefined_ behavior and 
arguably doesn't matter. The caller violated the pre-condition. They get what 
they get. The behavior is completely undefined at that point. You just put in 
assertions to test pre-conditions so that you can find bugs in the calling 
code. 
As soon as you're testing that an AssertError is thrown, you're testing 
behavior 
that DbC considers undefined. DbC says that if you give a function input that 
does not violate its pre-conditions, the function will give you output which 
does not violate its post-conditions. It says nothing about what happens when 
you give it input which violates your pre-conditions. All bets are off at that 
point. You violated the contract.

So, testing your pre-conditions with assertions is simply testing that the 
caller code is correct. The function itself doesn't care whether the input was 
correct or not. It's only obligated to return valid values when the contract is 
kept. If the caller violates the contract, then tough luck for it.

The difference with exceptions is that you're _requiring_ that the caller give 
you correct input and erroring out if it doesn't.

Regardless, if you really want to test that your pre-condition checks are 
correct, then just test them. I'd argue against it because you're testing test 
code, and that shouldn't be necessary, but if you're going to test that your 
assertions work correctly, then test them right.

  So, what it really comes down to is whether you looking to test the
  code which calls your function and are therefore willing to have that
  code give you bad input and let your function process it anyway (when
  assertions aren't compiled in) and you therefore use assertions, _or_
  you're looking to guarantee that your function does _not_ continue if
  the contract is violated, and you want to _always_ error out - in which
  case you use Exceptions.
 
 Yep. All in all, a very useful clarification for me.
 
 As a side note: Why isn't there a release-version of the contract
 mechanisms? I would've thought that contracts would be even more useful
 between different programmers, than just 

Re: Initializing a class pointer

2011-02-26 Thread Tyro[a.c.edwards]

On 2/27/2011 9:46 AM, Tyro[a.c.edwards] wrote:

On 2/27/2011 8:52 AM, Simen kjaeraas wrote:

Tyro[a.c.edwards] nos...@home.com wrote:


I'm trying to convert some c++ code that defines

T func(par...)
{
Controller * pCtrl = WinGetLongController * (hwnd);
.
.
.
switch(msg)
{
case FirstMatch:
pCtrl = new Controller (hwnd, reinterpret_castCREATESTRUCT *
(lParam));
break;
}
}

I'm not sure why I need a pointer to the class, just trying to figure
it out.


Ah. You would not need a pointer to the class in D. Instead, your
function
would look something like this:

T funct(par...)
{
auto pCtrl = WinGetLong!Controller(hwnd);
...
switch(msg)
{
case FirstMatch:
pCtrl = new Controller(hWnd, cast(CREATESTRUCT*)lParam);
break;
}
}

C++ classes are in some ways more akin to D structs, in that:

class A {};

void foo(){
A bar;
}

bar would be allocated on the stack in C++, while in D bar would be a
pointer to a class instance on the heap. (well, it would be null, but
when you set it to something, that something would reside on the heap)



Ok, that's essentially what I have, except that I used Controller pCtrl
vice auto. WinGetLong however, is a template that calls
GetWindowLongPtrA() and casts it's result (in this case) to Controller.
GetWindowLongPtrA() returns LONG_PTR (aka int) and therefore fails
miserably on the cast attempt. On the reverse, there is a WinSetLong
that attempts to cast Controller to int for use with
SetWindowLongPtrA(). Neither of these functions complain when I use
Controller* but I end up with the problem of trying to initialize a
pointer with a reference to Controller.


By the way, in original C++ code WinGetLong and WinSetLong are both 
using a reinterpret_cast to achieve this monkey magic. To the best of my 
knowledge, there is no reinterpret_cast facility in D. So the question 
would be, why would it have been necessary to use reinterpret_cast in 
the first place and how can similar effect be obtained in D? What was 
being reinterpreted? Was it the address of the class or the value some 
private value contained therein?


Re: How do you test pre-/post-conditions and invariants?

2011-02-26 Thread Jonathan M Davis
On Saturday 26 February 2011 08:23:41 David Nadlinger wrote:
 On 2/26/11 4:08 PM, Magnus Lie Hetland wrote:
  On 2011-02-26 15:20:19 +0100, David Nadlinger said:
  On 2/26/11 1:15 PM, Jonathan M Davis wrote:
  [...] And from a perfectly practical standpoint, as soon as your code
  ends
  up in a library, assertions are generally useless anyway,[...]
  
  I don't quite think asserts are useless in libraries. If you need to
  care about performance in a library, you hit cases quite frequently
  where sanity-checking the input would be too expensive to be done in
  release mode, and thus you can't specify behavior on invalid input as
  part of your API using exceptions. Nevertheless, it is still useful to
  people using your library to get notified when they are messing
  something up as early as possible in debug mode, which is precisely
  what asserts are made for, at least in my opinion.
  
  But that would only work if they had access to the source, or a version
  not compiled in release mode, right?
 
 True, but as shipping debug libraries and headers is precisely what SDKs
 are for, I don't see much of a problem there. Heck, even Microsoft's C
 Runtime comes with an extra debug version…

Sure, you _can_ use assertions in public APIs, but you _can't_ rely on them 
being there, because the programmer using the API could be using a release 
version.

If you really want to have an error for giving bad input, then it should be an 
Exception of some kind. Assertions are there for testing code. They go away. 
Also, it just plain looks bad when your library throws an AssertError. Since 
assertions are used to test the internal logic of your code, it makes it look 
like _your_ code is wrong rather than the code which is using your code.

You can't rely on assertions being in a library, so if you want those checks to 
be guaranteed to take place, you need to use exceptions. If you want the check 
to always take place, you need to use exceptions. If you want to report an 
input 
error as opposed to reporting a code logic error, then you should be using 
exceptions. So, assertions make great sense for testing that your code is 
correct, but when you hand it off to someone else to use, it shouldn't 
generally 
be throwing AssertErrors. There are times where that makes sense (particularly 
in code that _needs_ to be highly efficient and can't afford the extra checks 
in 
release mode), but at that point, you're saying that the check is _not_ part of 
the API (just an extra service to the programmer using it), and you're saying 
that you're willing to deal with programmers thinking that your code is faulty, 
because it's throwing AssertErrors.

What I've been saying is essentially how Phobos goes about dealing with 
assertions and exceptions in its functions.

- Jonathan M Davis


Re: Additional path for libs

2011-02-26 Thread Bekenn

Apologies for the late reply, but this could help:

As you've already seen in the other replies, the provided sc.ini file is 
confounding your attempts at setting the LIB environment variable. 
However, OPTLINK's search path for sc.ini includes the current 
directory, so if you're reluctant to alter the original file, you can 
just create an empty sc.ini in the current directory.  You are then free 
to redefine LIB and DFLAGS to whatever you like.


Here's an excerpt from one of my makefiles (I use Microsoft's NMAKE):

$(EXECUTABLE) : sc.ini $(SOURCES)
$(D) $(SOURCES) $(LIBS) $(DFLAGS) $(DEXEFLAGS)
@move /y $(APPNAME).map $(@D)  NUL

sc.ini :
@copy NUL sc.ini


Re: Interfacing with c and platform dependent sizes

2011-02-26 Thread Bekenn

On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:

BTW, I think long long is a gnu extension, it's not standard C (I don't
think long long exists in Visual C for instance).


I'm pretty sure it's standard as of C99 (though not yet for C++; that's 
coming with C++0x).  MSVC does indeed support it.


Re: Initializing a class pointer

2011-02-26 Thread Bekenn

On 2/26/2011 5:33 PM, Tyro[a.c.edwards] wrote:

Ok, that's essentially what I have, except that I used Controller pCtrl
vice auto. WinGetLong however, is a template that calls
GetWindowLongPtrA() and casts it's result (in this case) to Controller.
GetWindowLongPtrA() returns LONG_PTR (aka int) and therefore fails
miserably on the cast attempt. On the reverse, there is a WinSetLong
that attempts to cast Controller to int for use with
SetWindowLongPtrA(). Neither of these functions complain when I use
Controller* but I end up with the problem of trying to initialize a
pointer with a reference to Controller.


By the way, in original C++ code WinGetLong and WinSetLong are both
using a reinterpret_cast to achieve this monkey magic. To the best of my
knowledge, there is no reinterpret_cast facility in D. So the question
would be, why would it have been necessary to use reinterpret_cast in
the first place and how can similar effect be obtained in D? What was
being reinterpreted? Was it the address of the class or the value some
private value contained therein?


What you need here is a double cast; class references can be cast to 
void*, and from there to LONG_PTR.  The reverse also works:


auto WinGetLong(T)(HWND hwnd)
{
return cast(T)cast(void*)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
}

void WinSetLong(T)(HWND hwnd, T o)
{
SetWindowLongPtrA(hwnd, GWLP_USERDATA, cast(LONG_PTR)cast(void*)o;
}