Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Dereference syntax when accessing a struct element in C

The code demo below works but I’m not sure it’s syntactically correct.

For example, should this

X = *((QWORD*)(pRegCtx->X));

be replaced with

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

X = *(QWORD*)(pRegCtx->X);

Plus code looks odd using a QWORD cast

RegisterContext RegCtx = { (QWORD)&X };

Without the (QWORD) cast, the linux c compiler reports:

warning: initialization of ‘long unsigned int’ from ‘QWORD *’ {aka
‘long unsigned int *’} makes integer from pointer without a cast
[-Wint-conversion]

Any tips on how make it conform better to the C89 standard?

https://www.onlinegdb.com/0pBta5XO2

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

typedef         uint64_t QWORD;
typedef         uint32_t DWORD;
typedef         uint16_t WORD;
typedef         uint8_t  BYTE;

typedef struct  RegisterContext
{
          QWORD X;
} RegisterContext, *PREGISTERCONTEXT;


void MyFun(PREGISTERCONTEXT pRegCtx)
{
     QWORD X = 0;
     X = *((QWORD*)(pRegCtx->X));
     X += 42;
     *((QWORD*)(pRegCtx->X)) = X;
 } 

int main(void)
{    
         QWORD X = 0;
         RegisterContext RegCtx = { (QWORD)&X };
   
         MyFun(&RegCtx);
         
         // Answer to the Ultimate Question of Life, the Universe, and Everything
         printf("X=%lu\n",X);

    return 0;
}

>Solution :

  1. Never hide pointers and arrays behind typedefs.
  2. Use standard int types instead of QWORD and similar. There is no reason to introduce new strange types.
  3. Use correct printf formats.
  4. Do not overcomplicate simple things.
typedef struct  RegisterContext
{
          uint64_t X;
} RegisterContext;


void MyFun(RegisterContext *pRegCtx)
{
     uint64_t X = 0;
     X = pRegCtx->X;
     X += 42;
     pRegCtx->X = X;
 } 

int main(void)
{    
    uint64_t X = 0;
    RegisterContext RegCtx = { X };
   
     MyFun(&RegCtx);
         
     X = RegCtx.X;
      
     printf("X=%"PRIu64"\n", RegCtx.X);

     return 0;
}

https://godbolt.org/z/noPW46W3r

If your structure represents the layout of the hardware register mapped into the address space then you need to use macros.

typedef struct  RegisterContext
{
      uint64_t X;
      uint64_t Y;
      uint64_t Z;
      uint64_t W;
} RegisterContext;


#define REG1ADDRESS 0x40000340

#define REG1 ((volatile RegisterContext*)REG1ADDRESS)


void setX(void)  
{
    REG1 -> Z = 0x45654564;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading