Jump to page: 1 25  
Page
Thread overview
March 16
What's going on here?
```
import std.digest.md, std.stdio;

void main() {
    string ans = hex("qwertyuiop");
    writeln(ans);
}

string hex(string arg) {
    string ans = md5Of(arg).toHexString();
    writeln(ans);
    return ans;
}
```
This compiles, and when run writes out corrupt nonsense from the writeln in main, while just before that writing out 6EEA9B7EF19179A06954EDD0F6C05CEB from the function hex.

If I replace md5Of(arg).toHexString() with toHexString(md5Of(arg)) it won't compile, claiming that "toHexString.d(11): Error: function expected before (), not module toHexString of type void". Yet the examples here
http://dlang.org/phobos/std_digest_md.html
use toHexString freely in this way. I thought I was using toHexString by UFCS, in the earlier example, but this appears to be untrue.

The return from the function hex above somehow corrupts the string returned, suggesting deallocation is occurring in some fashion. So I replaced md5Of(arg).toHexString() with md5Of(arg).toHexString().dup and the problem vanished. Now 6EEA9B7EF19179A06954EDD0F6C05CEB is printed out twice.

March 16
On Thursday, 16 March 2017 at 16:13:33 UTC, Carl Sturtivant wrote:
>     string ans = md5Of(arg).toHexString();

That is a major D design flaw biting you the same way it has bitten so many others.

See the red box in my documentation fork:

http://dpldocs.info/experimental-docs/std.digest.digest.toHexString.2.html

toHexString returns a static array... on the stack. Then the stupid language not only implicitly casts it to immutable, it also implicitly slices it, giving you a reference to mutable, temporary data pretending to be permanent, immutable data.

> If I replace md5Of(arg).toHexString() with toHexString(md5Of(arg))....

That works for me though... maybe it is just a version mismatch or something, since toHexString is in a different module than md5of.
March 16
On Thu, Mar 16, 2017 at 04:21:08PM +0000, Adam D. Ruppe via Digitalmars-d-learn wrote:
> On Thursday, 16 March 2017 at 16:13:33 UTC, Carl Sturtivant wrote:
> >     string ans = md5Of(arg).toHexString();
> 
> That is a major D design flaw biting you the same way it has bitten so many others.
> 
> See the red box in my documentation fork:
> 
> http://dpldocs.info/experimental-docs/std.digest.digest.toHexString.2.html
> 
> toHexString returns a static array... on the stack. Then the stupid language not only implicitly casts it to immutable, it also implicitly slices it, giving you a reference to mutable, temporary data pretending to be permanent, immutable data.

WAT?!  Why does the language allow implicitly casting from static array to string?!  How is that even remotely correct?  Is there a bug filed for this?


T

-- 
To provoke is to call someone stupid; to argue is to call each other stupid.
March 16
On Thursday, 16 March 2017 at 16:21:08 UTC, Adam D. Ruppe wrote:
> On Thursday, 16 March 2017 at 16:13:33 UTC, Carl Sturtivant wrote:
>>     string ans = md5Of(arg).toHexString();
>
> That is a major D design flaw biting you the same way it has bitten so many others.
>
> See the red box in my documentation fork:
>
> http://dpldocs.info/experimental-docs/std.digest.digest.toHexString.2.html
>
> toHexString returns a static array... on the stack. Then the stupid language not only implicitly casts it to immutable, it also implicitly slices it, giving you a reference to mutable, temporary data pretending to be permanent, immutable data.

Silently <expletive-deleted> cast to immutable without copying!??!! This is so wrong.

Yet the documentation says there's a toHexString that returns a string.
http://dlang.org/phobos/std_digest_digest.html#.toHexString
I don't understand the overload resolution implied at this link. How is a toHexString selected in
        string ans = md5Of(arg).toHexString();
?


March 16
On Thursday, 16 March 2017 at 16:21:08 UTC, Adam D. Ruppe wrote:
>> If I replace md5Of(arg).toHexString() with toHexString(md5Of(arg))....
>
> That works for me though... maybe it is just a version mismatch or something, since toHexString is in a different module than md5of.

I have this problem on Linux and Windows, at 64 bits on the former, and 32 on the latter, with simple clean installations of dmd 2.073.2 on Linux, 2.073.3 on Windows. Same error message.
"toHexString.d(11): Error: function expected before (), not module toHexString of type void"
Module???

March 16
On Thursday, 16 March 2017 at 16:47:14 UTC, Carl Sturtivant wrote:
> Silently <expletive-deleted> cast to immutable without copying!??!! This is so wrong.

It is the implicit slicing that I really want removed from the language, it serves no real benefit and brings a lot of accidental complexity. Casting the static array to immutable is actually OK in isolation, because it is a value type and thus a unique copy... but once you slice it, that promise is gone.

> Yet the documentation says there's a toHexString that returns a string.

Yes, indeed, it returns a string if it is passed a dynamic array.

Remember though, like I warned on my doc fork, overload resolution NEVER looks at the left hand side of the equation, it is always done on arguments alone.

The stupid auto return stuff Phobos loves so much obscures it, but md5Of returns a ubyte[16].

That calls the first overload, the one that returns char[num*2], since the argument most strongly matches the static array one. (Interestingly, if it didn't exist, the language would probably idiotically slice that ubyte[16] into a ubyte[] and we'd get right behavior, for the wrong reason. The implementation of the slice one does `new char[]` inside.)

If you explicitly sliced it before the call,

toHexString(md5Of(...)[]); // notice the []

then it would call the one that returns the string and be fine!

March 16
On Thursday, 16 March 2017 at 16:56:11 UTC, Carl Sturtivant wrote:
> "toHexString.d(11): Error: function expected before (), not module toHexString of type void"
> Module???

huh idk.

use my search engine btw!  http://dpldocs.info/toHexString

it is in `std.digest.digest` but that should be publicly imported.
March 16
On Thursday, 16 March 2017 at 16:46:43 UTC, H. S. Teoh wrote:
> WAT?!  Why does the language allow implicitly casting from static array to string?!  How is that even remotely correct?  Is there a bug filed for this?

Yeah, somewhere, bugzilla search sucks but I know it is in there somewhere. We've talked about it at some length, including JMD and I recently on github relating to the Phobos template constraint mess: https://github.com/dlang/phobos/pull/5259#issuecomment-285445535

He said Walter thinks one of those memory safety DIPs will moot it, but I completely disagree. Even if this code threw an error (which it ABSOLUTELY SHOULD for several reasons), the implicit slice still leads to convoluted Phobos constraints to deal with it sanely! (Well, IMO the sane option is to just disallow it in the constraint, but ohes noes teh broken c0dez)

In isolation, implicit slicing can make sense.... but not with templates. In isolation, implicit immutable can make sense... but not with implicit slicing.

We aren't getting rid of templates. They are useful. But implicit slicing? Please, just write `[]` if you want that, easy fix, and then we'd rescue the immutable cast too.
March 16
On Thursday, 16 March 2017 at 17:01:56 UTC, Adam D. Ruppe wrote:
> On Thursday, 16 March 2017 at 16:56:11 UTC, Carl Sturtivant wrote:
>> "toHexString.d(11): Error: function expected before (), not module toHexString of type void"
>> Module???
>
> huh idk.
>
> use my search engine btw!  http://dpldocs.info/toHexString
>
> it is in `std.digest.digest` but that should be publicly imported.

I did that, and it made no difference. :(

March 16
On Thursday, 16 March 2017 at 17:12:08 UTC, Carl Sturtivant wrote:
> I did that, and it made no difference. :(

wait a minute i just realized:

toHexString.d(11) in the error message

You named the file toHexString which means the *module* will be named toHexString by default...

So using the name like that the compiler will think you are referring to the module (of type void) instead of the function.

I'd say rename that module, but you can also use a fully-qualified name to disambiguate like `std.digest.digest.toHexString(md5Of(...))`

renaming the module is prolly easiest. either rename the file or throw a `module tohexstring;` up top. This btw is one of the reasons why the D style guide generally recommends all-lowercase module names, to make such conflicts less likely.
« First   ‹ Prev
1 2 3 4 5