Re: Getting a safe path for a temporary file
On Friday, October 27, 2017 21:38:55 Jonathan M Davis via Digitalmars-d- learn wrote: > Also, toStringz specifically returns an immutable(char)* - though looking > it over right now, I'd say that that's a bug for the overload that takes > const(char)[] instead of string. It really should return const(char)* in > that case. Actually, looking it over again, the return type is fine. That's the overload that always allocates a new string (since it assumes that the array could not have been from a string literal, since that would be a string and would go to the other overload), so even though the argument could have been const or mutable, what's returned is a pointer to a string, so immutable(char)* is correct. But https://issues.dlang.org/show_bug.cgi?id=15136 is still a problem for the other overload. - Jonathan M Davis
Re: Getting a safe path for a temporary file
On Saturday, October 28, 2017 02:46:00 Shriramana Sharma via Digitalmars-d- learn wrote: > On Wednesday, 25 October 2017 at 00:35:29 UTC, Ali Çehreli wrote: > > > char[] name = "/tmp/XX".dup; > > > > remain valid. The actual issue is the missing '\0'. So, > > > > consider toStringz in this case: > > https://dlang.org/library/std/string/to_stringz.html > > Thanks for your reply, but can you clarify exactly I should use > this? > > char[] name = "/tmp/XX".toStringz; > > gives > > (13): Error: cannot implicitly convert expression > `toStringz("/tmp/XX")` of type `immutable(char)*` to `char[]` > > So I tried: > > char[] name = "/tmp/XX".toStringz.dup; > > which gives > > (13): Error: template object.dup cannot deduce function from > argument types !()(immutable(char)*), candidates are: > /usr/include/dmd/druntime/import/object.d(1943): > object.dup(T : V[K], K, V)(T aa) > /usr/include/dmd/druntime/import/object.d(1979): > object.dup(T : V[K], K, V)(T* aa) > /usr/include/dmd/druntime/import/object.d(3764): > object.dup(T)(T[] a) if (!is(const(T) : T)) > /usr/include/dmd/druntime/import/object.d(3780): > object.dup(T)(const(T)[] a) if (is(const(T) : T)) > > And: > > char[] name = "/tmp/XX".dup.toStringz; > > gives the error (13): Error: cannot implicitly convert > expression `toStringz(dup("/tmp/XX"))` of type > `immutable(char)*` to `char[]` > > So I'm not sure what to do?! Well, for starters, toStringz returns a pointer, not a dynamic array. If you want a dynamic array that's null-terminated, then you'll need to explicitly put a null character on the end unless you're just going to use a string literal (which would mean a string, not a char[], so that won't work here). Also, toStringz specifically returns an immutable(char)* - though looking it over right now, I'd say that that's a bug for the overload that takes const(char)[] instead of string. It really should return const(char)* in that case. But regardless, that means that even changing char[] to char* wouldn't cut it if you're using toStringz, since you're starting with a string. If you want a specific constness, then you can use the more general function, std.utf.toUTFz, which works with multiple character types and differing constness rather than being designed specifically for string like toStringz is. However, something to take into account is that toStringz and toUTFz don't always return the same string (and in fact, they probably never should, because the trick they use to check for the null character one past the end of the string doesn't always work correctly). So, if you're passing a string to a C function that's then going to mutate it, you don't want toStringz or toUTFZ. In that case, it's better to just manually put the null terminator at the end of the string. So, you probably would end up with something like char[] name = "/tmp/XX\0".dup; auto fd = mkstemp(name.ptr); Then when you return the name, you do something like name[0 .. $ - 1].idup; Alternatively, you could use a static array, but either way, you'd want to put the null terminator in there manually. And fromStringz really isn't necessary, since mkstemp is just going to fill in the array that you gave it, and you know exactly where the null terminator is going to be, since it's just filling in the X's rather than doing something that could end up putting a null terminator anywhere in the array. You can just slice the array to chop off the null terminator, and then dup it or idup if it's a static array (so that you don't return a slice of a local variable), or if it's a dynamic array, then either return it as-is or idup it if you want a string; you could even use std.exception.assumeUnique to just cast it to string if you know that no other references to that data exists (which they wouldn't if you allocated the string inside of the function). Also, you _really_ wouldn't want to use fromStringz if you used a static array, since fromStringz always returns a slice of the original input: inout(char)[] fromStringz(inout(char)* cString) @nogc @system pure nothrow { import core.stdc.string : strlen; return cString ? cString[0 .. strlen(cString)] : null; } But if I were you, I'd just create a char[] with an explicit null terminator, and then afterwards, slice off the null character, and pass it to assumeUnique to get a string, since then you allocate only once and don't have to copy the contents of the array. - Jonathan M Davis
Re: Why is length being tested on an int?
On Saturday, October 28, 2017 02:38:43 Shriramana Sharma via Digitalmars-d- learn wrote: > Hello. I want a function to be able to take any arguments like > write() and print them out but quoting string arguments of length > more than 1. So I write the following quote: > > import std.stdio; > string myFunc(string arg) { return '\"' ~ arg ~ '\"'; } > void myWrite(T ...)(T args) > { > foreach (arg; args) > if (is(typeof(arg) == string) && arg.length > 1) > write(myFunc(arg)); > else > write(arg); > } > void main() { myWrite("Hello", 1, "c"); } > > However I am getting the error even when compiling: > > (6): Error: no property 'length' for type 'int' > (7): Error: function .myFunc (string arg) is not > callable using argument types (int) > (11): Error: template instance .myWrite!(string, int, > string) error instantiating > > I am not sure why, given short circuit evaluation, it is testing > the length of the int argument? Or is it that the problem is at > compile time itself so short circuit doesn't come into play? > > How to rewrite the function so I don't get the error? > > Thanks! Okay. is(typeof(arg) == string) will be evaluated at compile time, because is expressions are compile time constructs. However, an if statement is a runtime construct, so it's going to be evaluated at runtime (which does look like it's probably what you want for arg.length > 1). So, what you're getting is essentially either if(true && arg.length > 1) write(myFunc(arg)) else write(arg); or if(false && arg.length > 1) write(myFunc(arg)) else write(arg); depending on the type of arg. In either case, arg.length has to compile. The evaluation of whether it's true or not may be shortcutted, but that doesn't mean that its semantics don't have to be valid. You're going to need to break up what you're doing. e.g. static if(is(typeof(arg) == string)) { if(arg.length > 1) write(myFunc(arg)); else write(arg); } else write(arg); The other thing is that even with a static if and all of the conditions being compile-time (which they need to be for a static if), && and || don't shortcut the semantic check any more than that gets shortcutted with a runtime if statement. So, even if arg were completely a compile-time thing, static if(is(typeof(arg) == string) && arg.length > 1) { } would only be valid code if typeof(arg) has length (though the second condition would only be evaluated if arg were a string). There are times where it would be nice if && and || shortcutted the semantic check with static if, but for better or worse, they don't. - Jonathan M Davis
Re: Why is length being tested on an int?
On Saturday, 28 October 2017 at 02:38:43 UTC, Shriramana Sharma wrote: if (is(typeof(arg) == string) && arg.length > 1) I am not sure why, given short circuit evaluation, it is testing the length of the int argument? That's a runtime check and therefore the code must run to be short circuited at all... which means it must compile the whole thing first. Break the is() part into a separate static if, then put the runtime length check inside that. More like static if(is(typeof(arg) == string)) { if(arg.length > 1) // handle else // string of short length } else { // not a string }
Re: Getting a safe path for a temporary file
On Wednesday, 25 October 2017 at 00:35:29 UTC, Ali Çehreli wrote: > char[] name = "/tmp/XX".dup; remain valid. The actual issue is the missing '\0'. So, consider toStringz in this case: https://dlang.org/library/std/string/to_stringz.html Thanks for your reply, but can you clarify exactly I should use this? char[] name = "/tmp/XX".toStringz; gives (13): Error: cannot implicitly convert expression `toStringz("/tmp/XX")` of type `immutable(char)*` to `char[]` So I tried: char[] name = "/tmp/XX".toStringz.dup; which gives (13): Error: template object.dup cannot deduce function from argument types !()(immutable(char)*), candidates are: /usr/include/dmd/druntime/import/object.d(1943): object.dup(T : V[K], K, V)(T aa) /usr/include/dmd/druntime/import/object.d(1979): object.dup(T : V[K], K, V)(T* aa) /usr/include/dmd/druntime/import/object.d(3764): object.dup(T)(T[] a) if (!is(const(T) : T)) /usr/include/dmd/druntime/import/object.d(3780): object.dup(T)(const(T)[] a) if (is(const(T) : T)) And: char[] name = "/tmp/XX".dup.toStringz; gives the error (13): Error: cannot implicitly convert expression `toStringz(dup("/tmp/XX"))` of type `immutable(char)*` to `char[]` So I'm not sure what to do?!
Why is length being tested on an int?
Hello. I want a function to be able to take any arguments like write() and print them out but quoting string arguments of length more than 1. So I write the following quote: import std.stdio; string myFunc(string arg) { return '\"' ~ arg ~ '\"'; } void myWrite(T ...)(T args) { foreach (arg; args) if (is(typeof(arg) == string) && arg.length > 1) write(myFunc(arg)); else write(arg); } void main() { myWrite("Hello", 1, "c"); } However I am getting the error even when compiling: (6): Error: no property 'length' for type 'int' (7): Error: function .myFunc (string arg) is not callable using argument types (int) (11): Error: template instance .myWrite!(string, int, string) error instantiating I am not sure why, given short circuit evaluation, it is testing the length of the int argument? Or is it that the problem is at compile time itself so short circuit doesn't come into play? How to rewrite the function so I don't get the error? Thanks!
Re: Just starting with D (linking with C++)
On Friday, 27 October 2017 at 17:14:20 UTC, sivakon wrote: I want to use C++ libraries for machine learning and deep learning. How do I add C++ libraries to my d code. on FreeBSD, I use: for C static binding: -- clang -c sample.c dmd -L-lc foo.d sample.o or ldc -L-lc foo.d sample.o for c++ static binding: --- clang++ -c sample.cpp dmd -L-lc++ foo.d sample.o or ldc -L-lc++ foo.d sample.o There is nice article here that was pretty interesting too: https://www.gamedev.net/blogs/entry/2254003-binding-d-to-c/
Re: Why 2 ^^ 1 ^^ 2 = 2?
On Thursday, 26 October 2017 at 10:02:54 UTC, Kagamin wrote: On Sunday, 22 October 2017 at 22:28:48 UTC, Ivan Kazmenko wrote: Yeah, and a height-3 tower $a^{b^c}$ (TEX notation) Is $a^{b^c}$ the same as ${a^b}^c$ ? They are drawn slightly differently, so I suppose it's ambiguous indeed. Surely not the same. "3 to the power of (3 to the power of 3)" is "3 to the power of 27", or 7,625,597,484,987. "(3 to the power of 3) to the power of 3" is "27 to the power of 3", or 2187. For an argument, the TEX command "^" accepts either a single character or a bracket-enclosed string of arbitrary length. So $3^3^3$ indeed transforms to ${3^3}^3$, but not for some deeper reason this time. Ivan Kazmenko.
Re: Just starting with D (linking with C++)
On Friday, 27 October 2017 at 17:43:08 UTC, sivakon wrote: On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote: This should work: dmd foo.d Sample.o Just like the C examples from the D blog: https://dlang.org/blog/2017/10/25/dmd-windows-and-c/ Just used this! Got this error! sample.o: In function `foo(int, int, int)': sample.cpp:(.text+0x17): undefined reference to `std::cout' Sorry, just responded quickly from my tablet, didn't try it out first. There's actually a variant of this sample that is run as a test from the dmd compiler testsuite, so it is checked hundreds of times a day for pending pull requests, on all officially supported platforms by the auto-tester: https://auto-tester.puremagic.com/pulls.ghtml?projectid=1 https://github.com/dlang/dmd/blob/master/test/runnable/extra-files/cppb.cpp#L41 https://github.com/dlang/dmd/blob/master/test/runnable/cppa.d#L25 Looking at the D script that runs each compiler test, it adds the following flag for all C++ objects: https://github.com/dlang/dmd/blob/master/test/d_do_test.d#L499 So adding that flag got your example to work for me: dmd -L-lstdc++ foo.d Sample.o
Re: Just starting with D (linking with C++)
On 10/27/17 1:43 PM, sivakon wrote: On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote: This should work: dmd foo.d Sample.o Just like the C examples from the D blog: https://dlang.org/blog/2017/10/25/dmd-windows-and-c/ Just used this! Got this error! sample.o: In function `foo(int, int, int)': sample.cpp:(.text+0x17): undefined reference to `std::cout' You need to link against the C++ standard library. On my system, it appears to be -lc++. So in order to pass this value to the linker, use the dmd parameter -L-lc++ In order to find out what the name of the c++ library is, you need to compile a C++ program with the -v option. The linker step will show the library parameters you need to send to dmd. -Steve
Re: Just starting with D (linking with C++)
On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote: This should work: dmd foo.d Sample.o Just like the C examples from the D blog: https://dlang.org/blog/2017/10/25/dmd-windows-and-c/ Just used this! Got this error! sample.o: In function `foo(int, int, int)': sample.cpp:(.text+0x17): undefined reference to `std::cout'
Re: Just starting with D (linking with C++)
On Friday, 27 October 2017 at 17:14:20 UTC, sivakon wrote: Hi, Just started to work with D. Great language. I want to use C++ libraries for machine learning and deep learning. How do I add C++ libraries to my d code. For example, //sample.cpp #include using namespace std; int foo(int i, int j, int k) { cout << "i = " << i << endl; cout << "j = " << j << endl; cout << "k = " << k << endl; return 7; } //foo.d extern (C++) int foo(int i, int j, int k); void main() { foo(1,2,3); } How do I compile and link each of them to produce the result? dmd -c foo.d gcc -c Sample.cpp Both of them get me .o files. Where do I go from there? Thanks, Siv This should work: dmd foo.d Sample.o Just like the C examples from the D blog: https://dlang.org/blog/2017/10/25/dmd-windows-and-c/
Just starting with D (linking with C++)
Hi, Just started to work with D. Great language. I want to use C++ libraries for machine learning and deep learning. How do I add C++ libraries to my d code. For example, //sample.cpp #include using namespace std; int foo(int i, int j, int k) { cout << "i = " << i << endl; cout << "j = " << j << endl; cout << "k = " << k << endl; return 7; } //foo.d extern (C++) int foo(int i, int j, int k); void main() { foo(1,2,3); } How do I compile and link each of them to produce the result? dmd -c foo.d gcc -c Sample.cpp Both of them get me .o files. Where do I go from there? Thanks, Siv
Re: Role of third argument to GC.addRange
On 10/27/17 10:18 AM, Nordlöw wrote: The docs for the third argument to https://dlang.org/library/core/memory/gc.add_range.html says: "The GC might use this information to improve scanning for pointers or to call finalizers." Can somebody elaborate a bit on what "improve scanning" means here? Currently, the TypeInfo is needed if you want to call the destructor of a struct. Eventually, if we ever have precise scanning, the TypeInfo may provide a way to only scan reference types within the block, eliminating sources of false pointers. -Steve
Re: Role of third argument to GC.addRange
On Friday, 27 October 2017 at 14:18:02 UTC, Nordlöw wrote: Can somebody elaborate a bit on what "improve scanning" means here? I believe it is so it can skip scanning stuff like ubyte[] for pointers and in the future might be used for precise scanning on structs with pointers and data combined.
Role of third argument to GC.addRange
The docs for the third argument to https://dlang.org/library/core/memory/gc.add_range.html says: "The GC might use this information to improve scanning for pointers or to call finalizers." Can somebody elaborate a bit on what "improve scanning" means here?
Re: Empty UDA for classes not allowed?
On Thursday, 26 October 2017 at 15:09:48 UTC, bauss wrote: Why is it not allowed to have empty UDAs for classes? Let's say we have an UDA like this: struct Exclude { } Then we want to put it on a class like: @Exclude class Foo { ... } This will fail with the following error: Error: type Exclude has no value But on everything else we can place an empty UDA like that ex. on a function: This is okay: @Exclude void foo() { ... } Can someone explain to me why it's not possible with classes? FWIW all parameterless UDA in LDC use a struct literal e.g. https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/attributes.d#L237