long long problem

K

karl_m

I'm having trouble with unsigned long long declarations on my SCO unix
7.1.1 compiler. Can you test the following code? I'm expecting both
printf functions to report 1. Thanks, karl m

#include <stdio.h>

typedef struct {
unsigned long long cnt:16;
unsigned long long right:48;
} Page;

typedef struct {
Page *frame;
} Bt1;

typedef struct {
Page frame[1];
} Bt2;

char buff[4096];

int main (int argc, char **argv)
{
Bt1 bt1[1];
Bt2 bt2[1];

bt1->frame = (Page*)buff;

bt1->frame->cnt = 1;
bt1->frame->right = 30;
printf ("cnt1 = %d\n", bt1->frame->cnt);

bt2->frame->cnt = 1;
bt2->frame->right = 30;
printf ("cnt2 = %d\n", bt2->frame->cnt);
}
 
K

Keith Thompson

I'm having trouble with unsigned long long declarations on my SCO unix
7.1.1 compiler. Can you test the following code? I'm expecting both
printf functions to report 1. Thanks, karl m

But you don't tell us how it behaves on your system.
#include <stdio.h>

typedef struct {
unsigned long long cnt:16;
unsigned long long right:48;
} Page;

C only requires support for bitfields of types signed int, plain int,
and unsigned int (and _Bool in C99). Many compilers support other
types of bitfields as an extension.
typedef struct {
Page *frame;
} Bt1;

typedef struct {
Page frame[1];
} Bt2;

char buff[4096];

int main (int argc, char **argv)
{
Bt1 bt1[1];
Bt2 bt2[1];

bt1->frame = (Page*)buff;

That's interesting. I was about to complain that bt1 is an array, not
a struct pointer, but of course the array name decays to a pointer in
most contexts, including the left operand of a "->". It's legal and
it works, but I've never seen that idiom before.

I would have declared:

Bt1 bt1;
Bt2 bt2;

and used bt1.frame rather than bt1->frame.

As for assigning frame to point to buff, there's no guarantee that
buff is properly aligned for an object of type Page (though it's
likely that you'll be "lucky" and it will be). If you want to
allocate space for a Page, either declare an object of type Page or
use malloc().
bt1->frame->cnt = 1;
bt1->frame->right = 30;
printf ("cnt1 = %d\n", bt1->frame->cnt);

You're using a "%d" format for an unsigned long long value. Try
"%lld". (I suspect that's the cause of your problem, but you didn't
tell us what problem, if any, you're actually having.)
bt2->frame->cnt = 1;
bt2->frame->right = 30;
printf ("cnt2 = %d\n", bt2->frame->cnt);

And again.

You should also return 0 from the main program. (It's not required in
C99, but it's good style anyway.)

BTW, when I ran the program, I got:

cnt1 = 1
cnt2 = 1
 
K

karl_m

Keith said:
But you don't tell us how it behaves on your system.

Sorry. I get cnt1 = 0 and cnt2 = 1

C only requires support for bitfields of types signed int, plain int,
and unsigned int (and _Bool in C99). Many compilers support other
types of bitfields as an extension.

Well, it compiles on Unixware. It's not working, though.
typedef struct {
Page *frame;
} Bt1;

typedef struct {
Page frame[1];
} Bt2;

char buff[4096];

int main (int argc, char **argv)
{
Bt1 bt1[1];
Bt2 bt2[1];

bt1->frame = (Page*)buff;

That's interesting. I was about to complain that bt1 is an array, not
a struct pointer, but of course the array name decays to a pointer in
most contexts, including the left operand of a "->". It's legal and
it works, but I've never seen that idiom before.

I use it all the time, everywhere. It allows for a quick
re-declaration off the stack and onto malloc'd memory.
I would have declared:

Bt1 bt1;
Bt2 bt2;

and used bt1.frame rather than bt1->frame.

As for assigning frame to point to buff, there's no guarantee that
buff is properly aligned for an object of type Page (though it's
likely that you'll be "lucky" and it will be). If you want to
allocate space for a Page, either declare an object of type Page or
use malloc().

I was trying to create a simplified version. I actually do use malloc
in the program.
You're using a "%d" format for an unsigned long long value. Try
"%lld". (I suspect that's the cause of your problem, but you didn't
tell us what problem, if any, you're actually having.)

You're right. On the little-endian machine I use, it doesn't matter.
And again.


You should also return 0 from the main program. (It's not required in
C99, but it's good style anyway.)

BTW, when I ran the program, I got:

cnt1 = 1
cnt2 = 1

Thanks! I guess Unixware is just plain broken. karl m
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top