Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 11, 2021 properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
A beginner question: How to pass strings properly to functions in D? Is there any allocation going on if just use a function as "myPrint"? In C++ I have often seen calls where one just passes a reference/const reference to a string to avoid allocation. C++: void myPrintCPP(const std::string& input){ ... } D: void myPrint(string text){ ... } void myPrintRef(ref string text) { ... } So the question is does a function call like (ref string ...) (myPrintRef) make any sense in D to avoid additional allocations? A D-Style String could be seen as "const(char)[]"? So as it is a slice it already is a kind of reference to some data elsewhere? Which means calling a function like "myPrint" in D wouldn't cause any allocation. Is this correct? Thank's for your help. |
January 12, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to zack | On 12/01/2021 3:12 AM, zack wrote: > A beginner question: How to pass strings properly to functions in D? > Is there any allocation going on if just use a function as "myPrint"? In C++ I have often seen calls where one just passes a reference/const reference to a string to avoid allocation. > > C++: > void myPrintCPP(const std::string& input){ ... } > > D: > void myPrint(string text){ ... } > void myPrintRef(ref string text) { ... } If you are modifying text the reference and want the caller to see the change, use this. > So the question is does a function call like (ref string ...) (myPrintRef) make any sense in D to avoid additional allocations? There are no allocations for this. > A D-Style String could be seen as "const(char)[]"? So as it is a slice it already is a kind of reference to some data elsewhere? Which means calling a function like "myPrint" in D wouldn't cause any allocation. Is this correct? alias string = immutable(char)[]; https://github.com/dlang/druntime/blob/master/src/object.d |
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to zack | On Monday, 11 January 2021 at 14:12:57 UTC, zack wrote: > A beginner question: How to pass strings properly to functions in D? > Is there any allocation going on if just use a function as "myPrint"? In C++ I have often seen calls where one just passes a reference/const reference to a string to avoid allocation. C++ strings are reference counted, I think, so it is more to avoid a reference count increment than to avoid a collection. > A D-Style String could be seen as "const(char)[]"? So as it is a slice it already is a kind of reference to some data elsewhere? Which means calling a function like "myPrint" in D wouldn't cause any allocation. Is this correct? D strings are backed by GC so they are passed by reference too. |
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Monday, 11 January 2021 at 15:23:23 UTC, Ola Fosheim Grøstad wrote: > On Monday, 11 January 2021 at 14:12:57 UTC, zack wrote: >> A beginner question: How to pass strings properly to functions in D? >> Is there any allocation going on if just use a function as "myPrint"? In C++ I have often seen calls where one just passes a reference/const reference to a string to avoid allocation. > > C++ strings are reference counted, I think, so it is more to avoid a reference count increment than to avoid a collection. I meant allocation... The following prints "1", so no allocation. #include <iostream> #include <string> std::string a("hello world"); void f(std::string b){ std::cout << (b.data() == a.data()) << std::endl; } int main() { f(a); } |
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Monday, 11 January 2021 at 15:25:58 UTC, Ola Fosheim Grøstad wrote:
> I meant allocation... The following prints "1", so no allocation.
Just tried on Windows with Visual Studio, it prints "0". So I guess this is platform/compiler dependent.
|
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to zack | On 1/11/21 8:22 AM, zack wrote:
> On Monday, 11 January 2021 at 15:25:58 UTC, Ola Fosheim Grøstad wrote:
>> I meant allocation... The following prints "1", so no allocation.
>
> Just tried on Windows with Visual Studio, it prints "0". So I guess this is platform/compiler dependent.
Yes. Earlier C++ string implementations used reference counting, which caused multi-threading complications; so, many implementations switched to copying.
Ali
|
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 11 January 2021 at 16:40:53 UTC, Ali Çehreli wrote:
> Yes. Earlier C++ string implementations used reference counting, which caused multi-threading complications; so, many implementations switched to copying.
Ah, I guess I've never used std::string for anything that requires speed. Turns out that cpp.sh is outdated.
|
January 11, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to zack | On Monday, 11 January 2021 at 14:12:57 UTC, zack wrote:
>
> D:
> void myPrint(string text){ ... }
> void myPrintRef(ref string text) { ... }
>
In D strings are immutable so there will be no copying when passing as function parameters. Strings are essentially like slices when passing them.
I usually use "const string text" because D has no implicit declaration of variables. So using "ref" will not create a variable. This is contrary to C++ where passing as "const std::string &text" has a performance benefit and also C++ creates a unnamed variable for you.
ex.
void myFunction1(const string text);
void myFunction2(const ref string text);
myFunction1("test");
myFunction2("test"); -------> error cannot create an implicit reference
then you have to do like this
string t = "text";
myFunction2(t);
This will work but you have to do the extra step by declaring t. Annoying as you cannot write text literals directly in the function parameters, therefore I do not use "ref" and it doesn't have a big benefit in D either.
|
January 12, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to zack | On Monday, 11 January 2021 at 14:12:57 UTC, zack wrote: > A beginner question: How to pass strings properly to functions in D? > Is there any allocation going on if just use a function as "myPrint"? In C++ I have often seen calls where one just passes a reference/const reference to a string to avoid allocation. > > C++: > void myPrintCPP(const std::string& input){ ... } > > D: > void myPrint(string text){ ... } > void myPrintRef(ref string text) { ... } In D, `string` is an abbreviation for the type immutable(char)[], i.e. slice of immutable char. The slice type is a pointer+length pair, a (T*, size_t) tuple, it is very lightweight. Using `ref T[]` (that includes `ref string` aka `ref immutable(char)[]` is the way if you want reassignments or expanding/shrinking of the array to be visible to the caller. Since the cost of copying a pointer and a length is very low, I'd just use this: void myPrint(string text) { ... } It'll be probably what you want. Since you cannot write the immutable characters, if you don't intend to reassign, expand, or shrink the string locally, you can use `in string text`. You can basically only read `in` parameters for information. What `in` buys you is that the compiler will figure out the best way to pass the object. C++'s const T& will reference always, which is worse than a copy for small types. D's `in` will copy if the compiler thinks it's cheaper than referencing. Give https://dlang.org/changelog/2.094.0.html#preview-in a read, if you want details about `in`. Use it when it applies. It also documents intent. |
January 12, 2021 Re: properly passing strings to functions? (C++ vs D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to IGotD- | On Monday, 11 January 2021 at 16:53:50 UTC, IGotD- wrote:
> I usually use "const string text" because D has no implicit declaration of variables. So using "ref" will not create a variable. This is contrary to C++ where passing as "const std::string &text" has a performance benefit and also C++ creates a unnamed variable for you.
Did you consider `in`? It will do that in some time and do it now with -preview=in.
If you're using `const`, in almost all cases, `in` will work, too, and be better (and shorter).
|
Copyright © 1999-2021 by the D Language Foundation