Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 26, 2007 4-character literal | ||||
---|---|---|---|---|
| ||||
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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | 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 Re: 4-character literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rick Mann | 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.
|
Copyright © 1999-2021 by the D Language Foundation