Help with structure element casting required 
Author Message
 Help with structure element casting required

#include <unistd.h>

struct calling_party_byte1_struct {
 unsigned char info_elem_id : 7;
   unsigned char filler1 : 1;

Quote:
};

struct calling_party_byte3_struct {
 unsigned char number_plan_id : 4;
 unsigned char type_of_number : 3;
   unsigned char filler1 : 1;

Quote:
};

struct calling_party_byte4_struct {
 unsigned char screening_indicator : 2;
 unsigned char spare : 3;
 unsigned char presentation_indicator : 2;
   unsigned char filler1 : 1;

Quote:
};

struct calling_party_byten_struct {
 unsigned char number_digits;

Quote:
};

struct calling_party_information_element {
 union {
  unsigned char cgp_value1;
  struct calling_party_byte1_struct cgp1struct;
 } uval;
 unsigned char info_elem_len;
 union {
  unsigned char cgp_value3;
  struct calling_party_byte3_struct cgp3struct;
 } uval3;
 union {
  unsigned char cgp_value4;
  struct calling_party_byte4_struct cgp4struct;
 } uval4 ;
 struct calling_party_byten_struct cgpnstruct[12];

Quote:
};

main()
{
 struct calling_party_information_element cgp;

 printf("CALLER: PI %d", (struct calling_party_byte4_struct
*)(cgp.uval4).presentation_indicator);

Quote:
}

Help.  Trying to figure out how to get the casting correct to print out the
presentation_indicator from source above.
using SCO OpenServer 5.0.5 with included C compiler.

thanx
murray
--



Tue, 13 May 2003 12:11:00 GMT  
 Help with structure element casting required


Quote:
>#include <unistd.h>

>struct calling_party_byte1_struct {
> unsigned char info_elem_id : 7;
>   unsigned char filler1 : 1;
>};

>struct calling_party_byte3_struct {
> unsigned char number_plan_id : 4;
> unsigned char type_of_number : 3;
>   unsigned char filler1 : 1;
>};

>struct calling_party_byte4_struct {
> unsigned char screening_indicator : 2;
> unsigned char spare : 3;
> unsigned char presentation_indicator : 2;
>   unsigned char filler1 : 1;
>};

>struct calling_party_byten_struct {
> unsigned char number_digits;
>};

>struct calling_party_information_element {
> union {
>  unsigned char cgp_value1;
>  struct calling_party_byte1_struct cgp1struct;
> } uval;
> unsigned char info_elem_len;
> union {
>  unsigned char cgp_value3;
>  struct calling_party_byte3_struct cgp3struct;
> } uval3;
> union {
>  unsigned char cgp_value4;
>  struct calling_party_byte4_struct cgp4struct;
> } uval4 ;
> struct calling_party_byten_struct cgpnstruct[12];
>};

>main()
>{
> struct calling_party_information_element cgp;

> printf("CALLER: PI %d", (struct calling_party_byte4_struct
>*)(cgp.uval4).presentation_indicator);
>}

>Help.  Trying to figure out how to get the casting correct to print out the
>presentation_indicator from source above.
>using SCO OpenServer 5.0.5 with included C compiler.

>thanx
>murray

You don't need any casting.

presentation_indicator is in struct calling_party_byte4_struct
cgp4struct is the struct calling_party_byte4_struct in union uval4
union uval4 is in struct calling_party_information_element
cgp is the variable of type struct calling_party_information_element

Therefore
        printf("CALLER: PI %d",
                   cgp.uval4.cgp4struct.presentation_indicator);

<<Remove the del for email>>
--



Wed, 14 May 2003 03:00:00 GMT  
 Help with structure element casting required

Quote:

> #include <unistd.h>

> struct calling_party_byte1_struct {
>  unsigned char info_elem_id : 7;
>From 6.7.2.1:

"A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed
int, unsigned int, or some other implementation-defined type."

You're relying on implementation-defined behaviour. There's no need.
You'll waste no more bits by using unsigned int.

<snip>

Quote:
>  unsigned char presentation_indicator : 2;

You might prefer to call this unsigned int presentation_indicator : 2

<snip>

Quote:

> main()
> {
>  struct calling_party_information_element cgp;

>  printf("CALLER: PI %d", (struct calling_party_byte4_struct
> *)(cgp.uval4).presentation_indicator);
> }

Your program would exhibit undefined behaviour if it compiled, but I
expect that's a consequence of your t{*filter*} on our behalf.

Quote:

> Help.  Trying to figure out how to get the casting correct to print out the
> presentation_indicator from source above.

No casting required. Use %u rather than %d. The line should be

printf("CALLER: PI %u", cgp.uval4.cgp4struct.presentation_indicator);

And you really ought to make it unsigned int : 2 rather than unsigned
char : 2.

--
Richard Heathfield
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.*-*-*.com/ ~scs/C-faq/top.html
K&R answers, C books, etc: http://www.*-*-*.com/
--



Wed, 14 May 2003 03:00:00 GMT  
 Help with structure element casting required

Quote:

> #include <unistd.h>

For printf(), you should include <stdio.h>.

Quote:
> struct calling_party_byte1_struct {

IMHO, "_struct" at the end of the name is useless as C already
requires the "struct" keyword in front of the name.  Typedefs and
C++ are a different matter.

Quote:
>  unsigned char info_elem_id : 7;
>    unsigned char filler1 : 1;

Filler bit-fields can be left unnamed.

Quote:
> };

[other structures elided -- are these from GSM, by the way?]

Quote:
>  printf("CALLER: PI %d", (struct calling_party_byte4_struct
> *)(cgp.uval4).presentation_indicator);

This is only three steps from a solution.  First, the dot
operator has higher precedence than the cast, so you need to take
the cast inside the parentheses:

  printf("CALLER: PI %d",
         ((struct calling_party_byte4_struct *) cgp.uval4)
         .presentation_indicator);

Second, this is casting a structure to a pointer which C does not
allow.  If you want a different-typed pointer pointing to the
structure, you need to cast the address of the structure:

  printf("CALLER: PI %d",
         ((struct calling_party_byte4_struct *) &cgp.uval4)
         .presentation_indicator);

Third, the outer dot operator expects to get a structure on its
left side but is given the address of one instead.  Change it to
an arrow:

  printf("CALLER: PI %d",
         ((struct calling_party_byte4_struct *) &cgp.uval4)
         ->presentation_indicator);

Then it will work.

Finally, note that uval4 is already an union so the cast isn't
actually needed:

  printf("CALLER: PI %d",
         cgp.uval4.cgp4struct.presentation_indicator);
--



Wed, 14 May 2003 03:00:00 GMT  
 Help with structure element casting required

Quote:

> You'll waste no more bits by using unsigned int.

I don't know about the SCO C compiler, but with GCC 2.95.2, the
following writes UC1: 1 and UI1: 4.

#include <stdio.h>
int main(void)
{
  struct UC1 { unsigned char a: 1; };
  struct UI1 { unsigned int a: 1; };
  printf("UC1: %zu\n", sizeof (struct UC1));
  printf("UI1: %zu\n", sizeof (struct UI1));
  return 0;

Quote:
}

Strangely, sizeof (struct UI1) drops to 1 too if I unname the
bit-field.

For full portability, the original poster could use an array of
bytes (unsigned char, until uint_least8_t becomes more commonly
available), explicit bit masks and lots of macros.

Quote:
> Use %u rather than %d.

This is certainly cleaner, but is it really required?  The
bit-field in question has only 2 bits and so the value fits in
int and va_arg can fetch it as int.  Can printf() use some other
mechanism internally?
--



Fri, 16 May 2003 11:03:47 GMT  
 Help with structure element casting required

Quote:
> Your mailer is including:

> >------_=_NextPart_000_01C0580A.0D9C933A
> >Content-Type: application/ms-tnef
> >Content-Transfer-Encoding: base64

This is very strange.  I'm using Gnus 5.7 which AFAIK doesn't
support MIME and certainly doesn't support application/ms-tnef.
Neither did I find any add-on Lisp package with "ms-tnef" in it.
Could you send the article back to me with full headers?

Quote:
> Please make it stop.

Certainly, as soon as I find what's causing it.
--



Fri, 16 May 2003 03:00:00 GMT  
 Help with structure element casting required

Quote:


> > You'll waste no more bits by using unsigned int.

> I don't know about the SCO C compiler, but with GCC 2.95.2, the
> following writes UC1: 1 and UI1: 4.

I don't know about unsigned char bit-fields, but the Standard defines
unsigned int bit-fields. For sure.

<snip>

Quote:

> For full portability, the original poster could use an array of
> bytes (unsigned char, until uint_least8_t becomes more commonly
> available), explicit bit masks and lots of macros.

Right. In fact, three macros are probably sufficient; one to set a bit,
one to clear a bit, and one to examine a bit.

Quote:

> > Use %u rather than %d.

> This is certainly cleaner, but is it really required?  The
> bit-field in question has only 2 bits and so the value fits in
> int and va_arg can fetch it as int.  Can printf() use some other
> mechanism internally?

<shrug> Since printf provides a mechanism for printing signed types, and
a separate mechanism for printing unsigned types, I can't help thinking
that it makes a lot of sense to use the right mechanism for the right
type. Even if, in the current instance, it seems to make little
difference, I don't see any value in getting into sloppy habits.

--
Richard Heathfield
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
--



Fri, 16 May 2003 03:00:00 GMT  
 Help with structure element casting required


Quote:
>I don't know about the SCO C compiler, but with GCC 2.95.2, the
>following writes UC1: 1 and UI1: 4.

>#include <stdio.h>
>int main(void)
>{
>  struct UC1 { unsigned char a: 1; };
>  struct UI1 { unsigned int a: 1; };
>  printf("UC1: %zu\n", sizeof (struct UC1));
>  printf("UI1: %zu\n", sizeof (struct UI1));
>  return 0;
>}

>Strangely, sizeof (struct UI1) drops to 1 too if I unname the
>bit-field.

Not that strange because the compiler can deduce that you cannot access
the bit field and so optimises the struct to its minimum size.

Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Fri, 16 May 2003 03:00:00 GMT  
 Help with structure element casting required

Quote:

> In fact, three macros are probably sufficient; one to set a bit,
> one to clear a bit, and one to examine a bit.

I was thinking of:

  #define CP0_INFO_ELEM_ID_SHIFT   0
  #define CP0_INFO_ELEM_ID_MASK    0x7F
  #define CP2_NUMBER_PLAN_ID_SHIFT 0
  #define CP2_NUMBER_PLAN_ID_MASK  0x0F
  #define CP2_TYPE_OF_NUMBER_SHIFT 4
  #define CP2_TYPE_OF_NUMBER_MASK  0x07

  unsigned number_plan = (bytes[2] >> CP2_TYPE_OF_NUMBER_SHIFT) & CP2_TYPE_OF_NUMBER_MASK;

or perhaps even:

  #define GETBITS(val,item) (((val) >> item##_SHIFT) & item##_MASK)

  /* Look out, this evaluates lval twice.  */
  #define SETBITS(lval,item,new) \
      ((lval) = (((lval) & ~(item##_MASK << item##_SHIFT)) \
                 | ((new) << item##_SHIFT)))

  unsigned number_plan = GETBITS(bytes[2], CP2_TYPE_OF_NUMBER)
--



Sun, 18 May 2003 09:04:39 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. casting of struct element void pointer casting

2. making pointers to structure elements using array elements

3. help on sizeof of structure element

4. Q. [Casting] Losing 2147483647 elements????

5. Newbie very puzzled - no cast required??

6. casting for varargs required?

7. Why is casting required here?

8. sizeof an element of a structure

9. printing structure elements with MACRO

10. Comparing Structure Elements

11. Setting structure array elements

12. Getting address of element of structure array.

 

 
Powered by phpBB® Forum Software