Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > C macro to declare unsigned long from "ABCD"

Reply
Thread Tools

C macro to declare unsigned long from "ABCD"

 
 
Andre
Guest
Posts: n/a
 
      03-09-2012
Dear all,

I would like to handle a table of 4-byte long strings by just declaring
them as an array of unsigned 32 bit values.
Of course, this can be done manually, but it would be great if a macro
XY existed, that, for example, from
XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344

Is anybody aware of a macro that does this?

Best regards,

Andre
 
Reply With Quote
 
 
 
 
JohnF
Guest
Posts: n/a
 
      03-09-2012
Andre <(E-Mail Removed)> wrote:
> I would like to handle a table of 4-byte long strings by just declaring
> them as an array of unsigned 32 bit values.
> Of course, this can be done manually, but it would be great if a macro
> XY existed, that, for example, from
> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344
> Is anybody aware of a macro that does this? Best regards, Andre


Maybe just try...
#include <stdio.h>
#define uint unsigned int
#define XY(s) (((uint)(*(s+3))) + 256*( ((uint)(*(s+2))) \
+ 256*( ((uint)(*(s+1))) + 256*((uint)(*s)) )))
int main ( int argc, char *argv[] ) {
unsigned int xy = XY((argc>1?argv[1]:"ABCD"));
printf("%08X\n",xy); }
--
John Forkosh ( mailto: http://www.velocityreviews.com/forums/(E-Mail Removed) where j=john and f=forkosh )
 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      03-09-2012
Andre <(E-Mail Removed)> wrote:
> I would like to handle a table of 4-byte long strings by just declaring
> them as an array of unsigned 32 bit values.
> Of course, this can be done manually, but it would be great if a macro
> XY existed, that, for example, from
> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344


Not sure what you mean by "declaration" here but perhaps some-
thing like this is what you're looking for

#include <stdio.h>
#include <stdint.h>

#define XY( x ) ( x[0] << 24 | x[1] << 16 | x[2] << 8 | x[3] )

int main( void )
{
uint32_t x = XY( "ABCD" );
printf( "0x%08x\n", x );
return 0;
}

Of course, the normal caveats apply, i.e. your relying on a
certain character encoding, that a char has 8 bits etc. And
that the macro argument is really something that is a pointer
to an array-like object with at least four chars.

Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Andre
Guest
Posts: n/a
 
      03-09-2012
On 09.03.2012 11:55, JohnF wrote:
> Andre<(E-Mail Removed)> wrote:
>> I would like to handle a table of 4-byte long strings by just declaring
>> them as an array of unsigned 32 bit values.
>> Of course, this can be done manually, but it would be great if a macro
>> XY existed, that, for example, from
>> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344
>> Is anybody aware of a macro that does this? Best regards, Andre

>
> Maybe just try...
> #include<stdio.h>
> #define uint unsigned int
> #define XY(s) (((uint)(*(s+3))) + 256*( ((uint)(*(s+2))) \
> + 256*( ((uint)(*(s+1))) + 256*((uint)(*s)) )))
> int main ( int argc, char *argv[] ) {
> unsigned int xy = XY((argc>1?argv[1]:"ABCD"));
> printf("%08X\n",xy); }


Cool, works.
I had expected that it wouldn't because of alignment...
 
Reply With Quote
 
Noob
Guest
Posts: n/a
 
      03-09-2012
Andre wrote:

> I would like to handle a table of 4-byte long strings by just declaring
> them as an array of unsigned 32 bit values.
> Of course, this can be done manually, but it would be great if a macro
> XY existed, that, for example, from
> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344
>
> Is anybody aware of a macro that does this?


First stab, no cigar

#define XY(s) ( s[0]<<24 | s[1]<<16 | s[2]<<8 | s[3] )
unsigned arr[] =
{
XY("ABCD"),
XY("EFGH"),
XY("IJKL"),
};

$ gcc mini.c
mini.c:4:3: error: initializer element is not constant
mini.c:4:3: error: (near initialization for 'arr[0]')
mini.c:5:3: error: initializer element is not constant
mini.c:5:3: error: (near initialization for 'arr[1]')
mini.c:6:3: error: initializer element is not constant
mini.c:6:3: error: (near initialization for 'arr[2]')
 
Reply With Quote
 
Noob
Guest
Posts: n/a
 
      03-09-2012
Noob wrote:

> Andre wrote:
>
>> I would like to handle a table of 4-byte long strings by just declaring
>> them as an array of unsigned 32 bit values.
>> Of course, this can be done manually, but it would be great if a macro
>> XY existed, that, for example, from
>> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344
>>
>> Is anybody aware of a macro that does this?

>
> First stab, no cigar
>
> #define XY(s) ( s[0]<<24 | s[1]<<16 | s[2]<<8 | s[3] )
> unsigned arr[] =
> {
> XY("ABCD"),
> XY("EFGH"),
> XY("IJKL"),
> };
>
> $ gcc mini.c
> mini.c:4:3: error: initializer element is not constant
> mini.c:4:3: error: (near initialization for 'arr[0]')
> mini.c:5:3: error: initializer element is not constant
> mini.c:5:3: error: (near initialization for 'arr[1]')
> mini.c:6:3: error: initializer element is not constant
> mini.c:6:3: error: (near initialization for 'arr[2]')


There is a work-around if you're willing to break the string up.

#define YX(A,B,C,D) ( A<<24 | B<<16 | C << 8 | D )
unsigned arr[] =
{
YX('A','B','C','D'),
YX('E','F','G','H'),
};

$ gcc -Wall -Wextra -Os -S mini.c
$ cat mini.s
.file "mini.c"
..globl _arr
.data
.align 4
_arr:
.long 1094861636
.long 1162233672


NB: 1094861636 = 0x41424344 and 1162233672 = 0x45464748
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-09-2012
Andre <(E-Mail Removed)> writes:

> I would like to handle a table of 4-byte long strings by just
> declaring them as an array of unsigned 32 bit values.


A word of warning... The result won't be a string even, when you
construct a character pointer to the int, because there will be no null
terminator.

<snip>
--
Ben.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-09-2012
On 3/9/2012 5:27 AM, Andre wrote:
> Dear all,
>
> I would like to handle a table of 4-byte long strings by just declaring
> them as an array of unsigned 32 bit values.
> Of course, this can be done manually, but it would be great if a macro
> XY existed, that, for example, from
> XY("ABCD") would generate a unsigned 32bit declaration like 0x41424344
>
> Is anybody aware of a macro that does this?


Others have offered macros that produce values from the
characters of strings, but note that the results are not
integer constant expressions. You could use them this way:

if (XY(string) == XY("ABCD")) ...

but not this way:

switch(XY(string)) {
case XY("ABCD"): ...
case XY("WXYZ"): ...
}

If this doesn't satisfy your need, perhaps you could describe
your situation more concretely. Someone's likely to come up with
another approach if it's needed.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      03-09-2012
On 03/09/2012 07:11 AM, Ben Bacarisse wrote:
> Noob <root@127.0.0.1> writes:
> <snip>
>> There is a work-around if you're willing to break the string up.
>>
>> #define YX(A,B,C,D) ( A<<24 | B<<16 | C << 8 | D )
>> unsigned arr[] =
>> {
>> YX('A','B','C','D'),
>> YX('E','F','G','H'),
>> };

>
> If the OP is prepared to step outside of portable C:
>
> unsigned arr[] =
> {
> 'ABCD',
> 'EFGH'
> };


He specified in the Subject: header that he's looking for unsigned long,
not unsigned. UINT_MAX could be as small as 0xFFFF, in which case it
would be absolutely guaranteed that this array does not contain the
values he's looking for.

You should identify precisely what the portability issue is. This code
must be accepted by any conforming C compiler - that's not what the
problem is. However, while C does allow character constants to contain
multiple characters, the value of such constants is an
implementation-defined int value. Since INT_MAX could be as small as
0x7FFF, on many implementations it would be impossible to form a
character constant with the right value. Even on implementations where
int is 32 bits, the value could be anything from INT_MIN to INT_MAX.
Without even considering systems which use character encoding
incompatible with ASCII, plausible values for 'ABCD' other than
0x41424344 include 0x44434241, 0x4142, 0x4443, 0x41, and 0x44.
--
James Kuyper
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      03-09-2012


"Andre" <(E-Mail Removed)> wrote in message
news:jjclv6$hnq$(E-Mail Removed)...
> Dear all,
>
> I would like to handle a table of 4-byte long strings by just declaring
> them as an array of unsigned 32 bit values.


Not sure if this is useful, but the following array of 4-char strings is
also accessed here via an int pointer (ie. an int array). (Substitute an
unsigned long here.)

#include <stdio.h>

char shortstrings[][4]={"ONE","TWO","THRE","FOUR","FIVE"};
int *ishortstrings=shortstrings;

int main(void)
{
int i;

for(i=0; i<5; ++i){
printf("%d:<%04X> <%.4s>\n", i, ishortstrings[i],
(char*)&ishortstrings[i] );
}

}

--
Bartc

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Having compilation error: no match for call to (const __gnu_cxx::hash<long long int>) (const long long int&) veryhotsausage C++ 1 07-04-2008 05:41 PM
unsigned long long int to long double Daniel Rudy C Programming 5 09-20-2005 02:37 AM
unsigned long to unsigned char ashtonn@gmail.com Python 1 06-01-2005 07:00 PM
Assigning unsigned long to unsigned long long George Marsaglia C Programming 1 07-08-2003 05:16 PM



Advertisments