Forum: Compiler & IDEs Cast between a pointer to object and an integral type


von Li (Gast)


Lesenswert?

Hi,


I want to calculate the address difference of var_a compared to base 
address of structure.
The solution works fine but I get the following warning:
**"Cast between a pointer to object and an integral type."**

    typedef struct
    {
        volatile int var_a;
        volatile int var_b;
    } struct_a;

    struct_a *pa;

Access:

    adrDiff_p = (int)&pa->var_a - (int)pa;

Do you have any better idea?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

offsetof()

von Li (Gast)


Lesenswert?

Jörg W. schrieb:
> offsetof()

I need a compiler independent solution. The code is running on a uC and 
the resources are limited.

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Offsetof is indeed compiler-independent.

Its a macro in the C stanndard.
See http://en.cppreference.com/w/cpp/types/offsetof
The wikipedia article on this topic has more information on it and 
features a sample implementation.
See https://en.m.wikipedia.org/wiki/Offsetof?wprov=sfla1

By the way: this is a german forum with a similar english one on 
embdev.net

Best regards,
N.G.

von cast as cast can :-((( (Gast)


Lesenswert?

please try this
1
typedef struct
2
{
3
  volatile int var_a;
4
  volatile int var_b;
5
  uint8_t var_c;
6
  uint8_t var_d;
7
} struct_a;
8
9
struct_a dummy;
10
struct_a *pa = &dummy;
11
12
int main(void) {
13
14
uint32_t addr_diff;
15
16
  addr_diff = (void *)&(pa->var_a) - (void *)pa;
17
  printf ("diff: %x\n\r", addr_diff);
18
19
  addr_diff = (void *)&(pa->var_b) - (void *)pa;
20
  printf ("diff: %x\n\r", addr_diff);
21
22
  addr_diff = (void *)&(pa->var_c) - (void *)pa;
23
  printf ("diff: %x\n\r", addr_diff);
24
25
  addr_diff = (void *)&(pa->var_d) - (void *)pa;
26
  printf ("diff: %x\n\r", addr_diff);
compiles without errors or warnings.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

N. G. schrieb:
> Its a macro in the C stanndard.

Even since C89, in <stddef.h>.

von Rolf M. (rmagnus)


Lesenswert?

cast as cast can :-((( schrieb:
> addr_diff = (void *)&(pa->var_a) - (void *)pa;

This is incorrect. Since void has no size, you cannot do pointer 
arithmetic with void*. You have to use char*.

> compiles without errors or warnings.

Well, I get a lot of errors and warnings from it. If I fix the missing 
headers and closing parenthesis in main, I still get:
1
voidp.c: In function ‘main’:
2
voidp.c:19:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
3
   addr_diff = (void *)&(pa->var_a) - (void *)pa;
4
                                    ^
5
voidp.c:22:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
6
   addr_diff = (void *)&(pa->var_b) - (void *)pa;
7
                                    ^
8
voidp.c:25:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
9
   addr_diff = (void *)&(pa->var_c) - (void *)pa;
10
                                    ^
11
voidp.c:28:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
12
   addr_diff = (void *)&(pa->var_d) - (void *)pa;
13
                                    ^

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> cast as cast can :-((( schrieb:
>> addr_diff = (void *)&(pa->var_a) - (void *)pa;
>
> This is incorrect. Since void has no size, you cannot do pointer
> arithmetic with void*.

FYI, gcc allows arithmetic on void*, adding even more confusion

http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

von cast as cast can :-((( (Gast)


Lesenswert?

Rolf M. schrieb:
> This is incorrect.

I got this with default compiler options after installation:

-------------- Build: Release in dummy (compiler: GNU GCC 
Compiler)---------------

mingw32-gcc.exe -Wall -O2  -c C:\...\C_CodeBlocks\dummy\main.c -o 
obj\Release\main.o
mingw32-g++.exe  -o bin\Release\dummy.exe obj\Release\main.o  -s
Output file is bin\Release\dummy.exe with size 19.00 KB
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

von Rolf M. (rmagnus)


Lesenswert?

cast as cast can :-((( schrieb:
> I got this with default compiler options after installation:

If you add -pedantic to the options, you'll get the warning. I recommend 
to add something like -std=c99 -pedantic -Wall -Wextra to the compiler 
command line.
Anyway, as I said, this is not correct C, even if gcc accepts it. The OP 
wanted a compiler independant solution.

Johann L. schrieb:
> FYI, gcc allows arithmetic on void*, adding even more confusion

Yes, unfortunately, it even does in strict ISO C mode.

von (prx) A. K. (prx)


Lesenswert?

cast as cast can :-((( schrieb:
> I got this with default compiler options after installation:

Having a compiler accept certain code does not imply that the code 
conforms to the standard.

Beitrag #5239015 wurde von einem Moderator gelöscht.
Beitrag #5239237 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.