mikrocontroller.net

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


Autor: Li (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
offsetof()

Autor: Li (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Jörg W. schrieb:
> offsetof()

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

Autor: N. G. (newgeneration) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: cast as cast can :-((( (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
please try this
typedef struct
{
  volatile int var_a;
  volatile int var_b;
  uint8_t var_c;
  uint8_t var_d;
} struct_a;

struct_a dummy;
struct_a *pa = &dummy;

int main(void) {

uint32_t addr_diff;

  addr_diff = (void *)&(pa->var_a) - (void *)pa;
  printf ("diff: %x\n\r", addr_diff);

  addr_diff = (void *)&(pa->var_b) - (void *)pa;
  printf ("diff: %x\n\r", addr_diff);

  addr_diff = (void *)&(pa->var_c) - (void *)pa;
  printf ("diff: %x\n\r", addr_diff);

  addr_diff = (void *)&(pa->var_d) - (void *)pa;
  printf ("diff: %x\n\r", addr_diff);
compiles without errors or warnings.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
N. G. schrieb:
> Its a macro in the C stanndard.

Even since C89, in <stddef.h>.

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht 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:
voidp.c: In function ‘main’:
voidp.c:19:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
   addr_diff = (void *)&(pa->var_a) - (void *)pa;
                                    ^
voidp.c:22:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
   addr_diff = (void *)&(pa->var_b) - (void *)pa;
                                    ^
voidp.c:25:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
   addr_diff = (void *)&(pa->var_c) - (void *)pa;
                                    ^
voidp.c:28:36: warning: pointer of type ‘void *’ used in subtraction [-Wpointer-arith]
   addr_diff = (void *)&(pa->var_d) - (void *)pa;
                                    ^

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht 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

Autor: cast as cast can :-((( (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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))

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
1 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
1 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.