Jump to page: 1 2
Thread overview
string initialization question.
Jul 30, 2010
dcoder
Jul 30, 2010
bearophile
Jul 30, 2010
Jonathan M Davis
Jul 30, 2010
Jonathan M Davis
Jul 30, 2010
bearophile
Jul 30, 2010
dcoder
Jul 30, 2010
Philippe Sigaud
Jul 30, 2010
Jonathan M Davis
Jul 31, 2010
Jason Spencer
Jul 30, 2010
Tomek Sowiński
Jul 30, 2010
Tomek Sowiński
July 30, 2010
Hello.

Is there anyway in D to convenient fill a string variable with a char say X times?

So, I'd like to do something like:

string divider( size, '-');    // C++ notation.
$divider = '-' x $size;        // perl notation.


I thought I could do the following:

const char divider[rowstr.length] = '-';

but the compiler complains about not having a constant integer expression.

thanks.


July 30, 2010
On Fri, 30 Jul 2010 11:24:41 -0400, dcoder <dcoder@devnull.com> wrote:

> Hello.
>
> Is there anyway in D to convenient fill a string variable with a char say X times?
>
> So, I'd like to do something like:
>
> string divider( size, '-');    // C++ notation.
> $divider = '-' x $size;        // perl notation.
>
>
> I thought I could do the following:
>
> const char divider[rowstr.length] = '-';
>
> but the compiler complains about not having a constant integer expression.
>
> thanks.

It's most likely complaining about rowstr.length not being a constant, not the '-'.  This works:

const char divider[5] = '-';

If you want to allocate a new array on the heap with '-' in it, I think there is a way, but I'm not sure how to do it.  I'm pretty sure there's a runtime function to do it.

-Steve
July 30, 2010
On Fri, 30 Jul 2010 11:35:15 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> 
> On Fri, 30 Jul 2010 11:24:41 -0400, dcoder <dcoder@devnull.com> wrote:
> 
> > Hello.
> >
> > Is there anyway in D to convenient fill a string variable with a char say X times?
> >
> > So, I'd like to do something like:
> >
> > string divider( size, '-');    // C++ notation.
> > $divider = '-' x $size;        // perl notation.
> >
> >
> > I thought I could do the following:
> >
> > const char divider[rowstr.length] = '-';
> >
> > but the compiler complains about not having a constant integer expression.
> >
> > thanks.
> 
> It's most likely complaining about rowstr.length not being a constant, not the '-'.  This works:
> 
> const char divider[5] = '-';
> 
> If you want to allocate a new array on the heap with '-' in it, I think there is a way, but I'm not sure how to do it.  I'm pretty sure there's a runtime function to do it.
> 
> -Steve

Something like this will work on the heap:

    char[] divider = new char[5];
    divider[] = '-';
July 30, 2010
On Fri, 30 Jul 2010 11:46:32 -0400, Justin Spahr-Summers <Justin.SpahrSummers@gmail.com> wrote:

> On Fri, 30 Jul 2010 11:35:15 -0400, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>>
>> If you want to allocate a new array on the heap with '-' in it, I think
>> there is a way, but I'm not sure how to do it.  I'm pretty sure there's a
>> runtime function to do it.
>>
> Something like this will work on the heap:
>
>     char[] divider = new char[5];
>     divider[] = '-';

That assigns 0xff to all divider chars, and then assigns '-'.  I think there's a way to do it without the initial assignment.

-Steve
July 30, 2010
Steven Schveighoffer:
> >     char[] divider = new char[5];
> >     divider[] = '-';
> 
> That assigns 0xff to all divider chars, and then assigns '-'.  I think there's a way to do it without the initial assignment.

In past there was some way to do that:
typedef char mchar = '-';
mchar[] divider = new mchar[5];

Now you have to initialize the dynamic array two times (using a char struct with alias this is probably not a good idea).
I have shown this problem, but I think Walter was not interested. Maybe LDC will able to optimize away the first initialization, I have an enhancement request for LLVM.

Bye,
bearophile
July 30, 2010
On Fri, 30 Jul 2010 12:46:20 -0400, bearophile <bearophileHUGS@lycos.com> wrote:

> Steven Schveighoffer:
>> >     char[] divider = new char[5];
>> >     divider[] = '-';
>>
>> That assigns 0xff to all divider chars, and then assigns '-'.  I think
>> there's a way to do it without the initial assignment.

I was wrong, I looked through the runtime and did not find such a function.

I think I may have read it in my copy of TDPL that I reviewed.

In any case, I think D deserves a way to do that.

>
> In past there was some way to do that:
> typedef char mchar = '-';
> mchar[] divider = new mchar[5];

As a way to initialize an array, this is horrible :)

> Now you have to initialize the dynamic array two times (using a char struct with alias this is probably not a good idea).
> I have shown this problem, but I think Walter was not interested. Maybe LDC will able to optimize away the first initialization, I have an enhancement request for LLVM.

I think a function to do it is fine, like makeArray('-', 5);

-Steve
July 30, 2010
On Friday, July 30, 2010 10:14:45 Steven Schveighoffer wrote:
> I think a function to do it is fine, like makeArray('-', 5);

Well, creating a function for producing an array literal and returning it using templates and string mixins wouldn't be all that hard, but if you want to create a dynamic array of arbitrary size at runtime, that's not going to work, and a makeArray() function would have exactly the same tools that you have to create an array of all the same value. So, it's not going to be any more efficient that what you can do.

int[] a = new int[](x);
a[] = val;

_should_ be fairly easily optimized by the compiler and thus really should be optimized down to an initialization rather than an initialization and an assignment.

A makeArray() function wouldn't hurt any, but I don't think that it would really buy us much. Of course, truth be told, I've always thought that the ability to construct a string or vector in C++ all of a single value was pretty useless. Obviously, some people find it useful at least once in a while, but I've never had much use for it. A makeArray() function would probably still be a good thing to have, but what we really need here is either a syntactic way to do it or for the compiler to optimize out the useless initialization (as well as inline makeArray()) so that you don't have to deal with the extra cost of setting everything twice.

- Jonathan M Davis
July 30, 2010
On Fri, 30 Jul 2010 15:56:36 -0400, Jonathan M Davis <jmdavisprog@gmail.com> wrote:

> On Friday, July 30, 2010 10:14:45 Steven Schveighoffer wrote:
>> I think a function to do it is fine, like makeArray('-', 5);
>
> Well, creating a function for producing an array literal and returning it using
> templates and string mixins wouldn't be all that hard, but if you want to create
> a dynamic array of arbitrary size at runtime, that's not going to work, and a
> makeArray() function would have exactly the same tools that you have to create
> an array of all the same value.

The function would call gc_malloc directly, which does not initialize the requested memory.  Actually, it would call a new run time function that I will write, which would initialize the array length also.

> So, it's not going to be any more efficient that
> what you can do.
>
> int[] a = new int[](x);
> a[] = val;
>
> _should_ be fairly easily optimized by the compiler and thus really should be
> optimized down to an initialization rather than an initialization and an
> assignment.

It's not.  The only runtime functions available to the compiler look like this:

_d_newarrayT(TypeInfo ti, size_t length);

-Steve
July 30, 2010
Jonathan M Davis:
> a makeArray() function would have exactly the same tools that you have to create an array of all the same value. So, it's not going to be any more efficient that what you can do.

Doesn't the D2 GC give you a lower level function to GC-allocate uninitialized memory? The GC in D1 has such function, so in D1 it's easy to create a makeArray().

Bye,
bearophile
July 30, 2010
Dnia 30-07-2010 o 17:24:41 dcoder <dcoder@devnull.com> napisał(a):

> Is there anyway in D to convenient fill a string variable with a char say X times?

If you need to only print, you can:

import std.stdio;
import std.range;

void main() {
    foreach (c; take(repeat('-'), 5))
        write(c);
}

I know, I know, you said *convenient* ;) I heard write(ln) is to print arbitrary ranges, so this'd come down to:

writeln(take(repeat('-'), 5));

and if universal call syntax worked correctly then even this would be possible:

writeln('-'.repeat.take(5));

much easier to type.

BTW, I stumbled on this when crafting the example:
http://d.puremagic.com/issues/show_bug.cgi?id=4537


Tomek
« First   ‹ Prev
1 2