Jump to page: 1 2
Thread overview
4-character literal
Jan 26, 2007
Rick Mann
Jan 26, 2007
Rick Mann
Jan 26, 2007
Gregor Richards
Jan 26, 2007
torhu
Jan 26, 2007
torhu
Jan 26, 2007
Rick Mann
Jan 26, 2007
Don Clugston
Jan 26, 2007
Gregor Richards
Jan 26, 2007
Joel C. Salomon
Jan 26, 2007
Rick Mann
Jan 26, 2007
Bill Baxter
Jan 27, 2007
Bill Baxter
Jan 26, 2007
Joel C. Salomon
Jan 26, 2007
janderson
Jan 26, 2007
Bill Baxter
Jan 26, 2007
Bill Baxter
January 26, 2007
Hi. I'm porting some Mac OS X (Carbon) code, and it relies heavily on a language feature that's been used on the Mac for decades: 4-byte character literals (like 'abcd'). In this case, I'm setting up enums that will be passed to OS APIs as 32-bit unsigned int parameters:

enum : uint
{
    kSomeConstantValue = 'abcd'
}

I tried using a 4-character string literal, but I get the following error when I do:

src/d/macos/carbon/carbonevents.d:29: Error: cannot implicitly convert expression ("ptrg") of type char[4] to uint src/d/macos/carbon/carbonevents.d:29: Error: Integer constant expression expected instead of cast(uint)"ptrg" src/d/macos/carbon/carbonevents.d:34: Error: cannot implicitly convert expression ("etrg") of type char[4] to uint src/d/macos/carbon/carbonevents.d:34: Error: Integer constant expression expected instead of cast(uint)"etrg"


I tried basing the enum on dchar, and I tried appending "d" to the end of the string literals, but neither works.

Any suggestions that don't involve significant re-writing of the 4-character literals? Thanks!


P.S. Grr. I don't like posting my unobfuscated email address to public sites.
January 26, 2007
Rick Mann Wrote:

> enum : uint
> {
>     kSomeConstantValue = 'abcd'
> }


I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).

So: how to I do the equivalent of 'abcd'?

Thanks!
January 26, 2007
Rick Mann wrote:
> Rick Mann Wrote:
> 
> 
>>enum : uint
>>{
>>    kSomeConstantValue = 'abcd'
>>}
> 
> 
> 
> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
> 
> So: how to I do the equivalent of 'abcd'?
> 
> Thanks!

Two solutions come to mind:

1) Will work, very ugly:
(cast(uint) 'a' << 24) + (cast(uint) 'b' << 16) + (cast(uint) 'c' << 8) + cast(uint) 'd'

2) Probably won't work:
*(cast(uint*) ("abcd".ptr))

3) Will work:
0x61626364

Each pretty bad. IMHO the original solution is pretty bad too :)

 - Gregor Richards
January 26, 2007
Rick Mann wrote:
> Rick Mann Wrote:
> 
>> enum : uint
>> {
>>     kSomeConstantValue = 'abcd'
>> }
> 
> 
> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
> 
> So: how to I do the equivalent of 'abcd'?
> 
> Thanks!

Try this.

template MAKE_ID(char[] s)
{
    static assert(s.length == 4);
    const uint ID = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
}

enum : uint
{
    kSomeConstantValue = MAKE_ID!("abcd")
}
January 26, 2007
torhu wrote:
> Rick Mann wrote:
>> Rick Mann Wrote:
>> 
>>> enum : uint
>>> {
>>>     kSomeConstantValue = 'abcd'
>>> }
>> 
>> 
>> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
>> 
>> So: how to I do the equivalent of 'abcd'?
>> 
>> Thanks!
> 
> Try this.
> 
> template MAKE_ID(char[] s)
> {
>      static assert(s.length == 4);
>      const uint ID = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
> }
> 
> enum : uint
> {
>      kSomeConstantValue = MAKE_ID!("abcd")
> }

Seems I was too quick.  Replace 'const uint ID' with 'const uint MAKE_ID', and it will compile.
January 26, 2007
Rick Mann wrote:
> Rick Mann Wrote:
> 
>> enum : uint
>> {
>>     kSomeConstantValue = 'abcd'
>> }
> 
> 
> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
> 
> So: how to I do the equivalent of 'abcd'?
> 
> Thanks!


To add to Gregor Richards suggestions, you may try an union (untested).

union Converter { uint asInt; char[4] chr; }
const Converter kSomeConstantValue = { chr : "abcd" };

//To get
kSomeConstantValue.asInt

-Joel
January 26, 2007
Rick Mann wrote:
> Rick Mann Wrote:
> 
>> enum : uint
>> {
>>     kSomeConstantValue = 'abcd'
>> }
> 
> 
> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
> 
> So: how to I do the equivalent of 'abcd'?
> 
> Thanks!

Interesting question.  How's this?

import std.stdio;

template touint(char[] T)
{
    static assert(T.length==4, "Integer constants must be of length 4");
    const uint touint =
        (cast(char)T[0] << 24)|
        (cast(char)T[1] << 16)|
        (cast(char)T[2] << 8)|
        (cast(char)T[3]);
}

enum
{
    kSomeConstantValue = touint!("xyzz")
}

void main()
{
    writefln("%x", kSomeConstantValue);
}

January 26, 2007
Bill Baxter wrote:
> Rick Mann wrote:
>> Rick Mann Wrote:
>>
>>> enum : uint
>>> {
>>>     kSomeConstantValue = 'abcd'
>>> }
>>
>>
>> I realized I was misunderstanding something else I saw, and that "abcd"d doesn't do what I thought (make a 4-byte character).
>>
>> So: how to I do the equivalent of 'abcd'?
>>
>> Thanks!
> 
> Interesting question.  How's this?
> 
> import std.stdio;
> 
> template touint(char[] T)
> {
>     static assert(T.length==4, "Integer constants must be of length 4");
>     const uint touint =
>         (cast(char)T[0] << 24)|
>         (cast(char)T[1] << 16)|
>         (cast(char)T[2] << 8)|
>         (cast(char)T[3]);
> }
> 
> enum
> {
>     kSomeConstantValue = touint!("xyzz")
> }
> 
> void main()
> {
>     writefln("%x", kSomeConstantValue);
> }
> 

Damn!  Torhu beat me too it!

--bb
January 26, 2007
torhu Wrote:

> Try this.
> 
> template MAKE_ID(char[] s)
> {
>      static assert(s.length == 4);
>      const uint ID = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
> }
> 
> enum : uint
> {
>      kSomeConstantValue = MAKE_ID!("abcd")
> }

Of the solutions proposed so far, this is probably the cleanest. Thanks!

Sadly, nothing's really as nice as just saying 'abcd'. What would it take to get multi-character literals added to the language?

January 26, 2007
Rick Mann wrote:
> torhu Wrote:
> 
>> Try this.
>>
>> template MAKE_ID(char[] s)
>> {
>>      static assert(s.length == 4);
>>      const uint ID = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
>> }
>>
>> enum : uint
>> {
>>      kSomeConstantValue = MAKE_ID!("abcd")
>> }
> 
> Of the solutions proposed so far, this is probably the cleanest. Thanks!
> 
> Sadly, nothing's really as nice as just saying 'abcd'. What would it take to get multi-character literals added to the language?
> 

In general, I don't think it could work in a useful way. 4-character literals do not fit in a uint. It only really works for ASCII.
« First   ‹ Prev
1 2