Thread overview
Playing const char[]s into an Array?
Mar 21, 2005
AEon
Mar 21, 2005
Alex Stevenson
Re: Placing const char[]s into an Array?
Mar 21, 2005
AEon
Mar 21, 2005
Alex Stevenson
Mar 21, 2005
pragma
Mar 21, 2005
jicman
March 21, 2005
<code>
// Hardcoded section names!
const char[9]	cfg_GENERAL		= "[General]";
const char[9]	cfg_WEAPONS		= "[Weapons]";
const char[10]	cfg_SUICIDES	= "[Suicides]";
const char[6]	cfg_MISC		= "[Misc]";
const char[5]	cfg_END			= "[end]";

const char[5][] cfg_Sections;
cfg_Sections[0]	=	cfg_GENERAL;
cfg_Sections[1]	=	cfg_WEAPONS;
cfg_Sections[2]	=	cfg_SUICIDES;
cfg_Sections[3]	=	cfg_MISC;
cfg_Sections[4]	=	cfg_END	;
</code>

As you can see I have defined several const chars. But I noted I need to place them into an array as well, to let me run them in loops.

I was actually trying to do something like this:

char[][] cfg_Sections = { cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES, cfg_MISC,
cfg_END};
-> Error: a struct is not a valid initializer for a char[][]

but that does not work either.

Any ideas?

AEon
March 21, 2005
Hi,

Array initialisers need to be specified in square brackets:

char[][] cfg_Sections = [ cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES, cfg_MISC, cfg_END ];

However this won't compile as DMD complains about non-const casts - i.e. it has to convert the static arrays (cfg_GENERAL etc) to dynamic arrays in the array initialiser. Changing the constants to dynamic arrays works though:

#import std.stdio;#
#const char[]cfg_GENERAL= "[General]";
#const char[]cfg_WEAPONS= "[Weapons]";
#const char[]cfg_SUICIDES= "[Suicides]";
#const char[]cfg_MISC= "[Misc]";
#const char[]cfg_END= "[end]";#
#char[][] cfg_Sections = [ cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES, cfg_MISC, cfg_END ];#
#int main()
#{
#   writefln( cfg_Sections[2] );
#   return 0;
#}

This prints "[Suicides]" as expected.

On Mon, 21 Mar 2005 16:34:59 +0000 (UTC), AEon <AEon_member@pathlink.com> wrote:

> char[][] cfg_Sections = { cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES, cfg_MISC,
> cfg_END};



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
March 21, 2005
Alex Stevenson,

>Array initialisers need to be specified in square brackets:
>
>char[][] cfg_Sections = [ cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES, cfg_MISC, cfg_END ];

Right... I had been looking for initializers for char[], then found an example for int[], that tipped my off :)

>However this won't compile as DMD complains about non-const casts - i.e. it has to convert the static arrays (cfg_GENERAL etc) to dynamic arrays in the array initialiser. Changing the constants to dynamic arrays works though:
>
>#import std.stdio;#
>#const char[]cfg_GENERAL= "[General]";
>#const char[]cfg_WEAPONS= "[Weapons]";
>#const char[]cfg_SUICIDES= "[Suicides]";
>#const char[]cfg_MISC= "[Misc]";
>#const char[]cfg_END= "[end]";#
>#char[][] cfg_Sections = [ cfg_GENERAL, cfg_WEAPONS, cfg_SUICIDES,
>cfg_MISC, cfg_END ];#
>#int main()
>#{
>#   writefln( cfg_Sections[2] );
>#   return 0;
>#}
>
>This prints "[Suicides]" as expected.

Yep, works like a charm.

I only started using "const char[6]" etc. because these are the equivalent to the #define commands it used to use in ANSI C.

Does the const in "const char[]cfg_END" actually mean anything. Since we are using a dynamic array?


Some solutions I had come up with:

// Will not work outside of a function though!
char[][] cfg_Sections;
cfg_Sections ~= cfg_GENERAL;
cfg_Sections ~= cfg_WEAPONS;
cfg_Sections ~= cfg_SUICIDES;
cfg_Sections ~= cfg_MISC;
cfg_Sections ~= cfg_END;

a more brute force method would have been:

char[][] cfg_Sections = [ "[General]", "[Weapons]", "[Suicides]", "[Misc]", "[end]" ];

AEon
March 21, 2005
On Mon, 21 Mar 2005 17:25:28 +0000 (UTC), AEon <AEon_member@pathlink.com> wrote:

> Alex Stevenson,
>
> <<SNIP>>
>
> Does the const in "const char[]cfg_END" actually mean anything. Since we are
> using a dynamic array?

It means the reference is constant:
cfg_END = cfg_SUICIDES;
cfg_END.length = 5;

both of these produce 'not an lvalue' errors from the compiler.

cfg_SUICIDES[2] = 'A'; compiles and runs under windows, but may crash under linux as the program is changing a value in the data segment of the program (where constants are stored).

>
>
> Some solutions I had come up with:
>
> // Will not work outside of a function though!
> char[][] cfg_Sections;
> cfg_Sections ~= cfg_GENERAL;
> cfg_Sections ~= cfg_WEAPONS;
> cfg_Sections ~= cfg_SUICIDES;
> cfg_Sections ~= cfg_MISC;
> cfg_Sections ~= cfg_END;

If you want this to be guaranteed to run, you could put it in a module constructor:

#char[][] cfg_Sections;
#
#static this()
#{
#    cfg_Sections ~= cfg_GENERAL;
#    cfg_Sections ~= cfg_WEAPONS;
#    cfg_Sections ~= cfg_SUICIDES;
#    cfg_Sections ~= cfg_MISC;
#    cfg_Sections ~= cfg_END;
#}

regards,
Alex
March 21, 2005
If it helps, here is a shim I rolled to help deal with array initalization:

private import std.string;

template makeArray(T){
T[] makeArray(...){
T[] result;
for(uint i=0; i<_arguments.length; i++){
if(_arguments[i] == typeid(T)){
result ~= *cast(T*)_argptr;
_argptr += T.sizeof;
}
else throw new Exception(format("(makeArray) element %d is not of type
%s.",toString(i+1),typeid(T).toString()));
}
return result;
}
}

It's not as pretty as the static array initalization syntax (using []) but it
gets the job done:

array = makeArray!(char[])("one", "two", "three", "four");

It'll take as many arguments as you can throw at it.

- EricAnderton at yahoo
March 21, 2005
In article <d1n9gj$lea$1@digitaldaemon.com>, pragma says...
>
>If it helps, here is a shim I rolled to help deal with array initalization:
>
>private import std.string;
>
>template makeArray(T){
>T[] makeArray(...){
>T[] result;
>for(uint i=0; i<_arguments.length; i++){
>if(_arguments[i] == typeid(T)){
>result ~= *cast(T*)_argptr;
>_argptr += T.sizeof;
>}
>else throw new Exception(format("(makeArray) element %d is not of type
>%s.",toString(i+1),typeid(T).toString()));
>}
>return result;
>}
>}
>
>It's not as pretty as the static array initalization syntax (using []) but it
>gets the job done:

Dude, until we get initialization, this is beautiful!  Thanks!

>
>array = makeArray!(char[])("one", "two", "three", "four");
>
>It'll take as many arguments as you can throw at it.
>
>- EricAnderton at yahoo