www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [ATmega] Pointer Umwandlung in C++ (C code)


Autor: Stefan Kuhne (sk-ac)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche C code nach C++ zu bringen.
Bisher lief es auch recht gut, nur bei dem Code für die FAT stehe ich 
vor einem Problem:
uint8_t FAT::fat_dir_entry_read_callback(uint8_t* buffer, offset_t offset, void* p)
{
    struct fat_read_dir_callback_arg* arg = p;
    struct fat_dir_entry_struct* dir_entry = arg->dir_entry;


Der Compiler meldet:

invalid conversion from 'void*' to 'fat_read_dir_callback_arg*'

Ganz sauber ist das ja auch wirklich nicht, aber unter C läuft der Code 
durch.
Jemand eine Idee?

Danke,
Stefan

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Kuhne schrieb:

> Ganz sauber ist das ja auch wirklich nicht, aber unter C läuft der Code
> durch.
> Jemand eine Idee?

Ja.
Wer Code von C nach C++ portiert, sollte über die Unterschiede der 
Sprachen Bescheid wissen :-)

In C ist es legal einen void Pointer an einen anderen zuzuweisen.
In C++ aber nicht. Da muss man casten (sofern man sich sicher ist, dass 
die Zuweisung an sich in Ordnung ist)

Autor: Stefan Kuhne (sk-ac)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das mit dem Cast hatte ich versucht und wollte es mit reinschreiben.
Das hatte ich so probiert:
struct fat_read_dir_callback_arg* arg = (fat_read_dir_callback_arg) p;

Der Compiler sagt:

no matching function for call to 
'fat_read_dir_callback_arg::fat_read_dir_callback_arg(void*&)'

Mist, wenn man die Meldung ganz liest sieht man was er will.

Aber wird das nicht eine Entlosschleife?
Obwohl wenn ich jedes Element dann einzeln zuweise geht sollte das gehen 
...

Danke,
Stefan

Autor: Rene H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, p ist ja auch ein Pointer, nach C könnte das so aussehen
struct fat_read_dir_callback_arg* arg = (fat_read_dir_callback_arg*) p;

Sauber wäre
struct fat_read_dir_callback_arg* arg = static_cast<fat_read_dir_callback_arg*>(p);

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Cast tut was anderes als die C-Zuweisung.
>
> struct fat_read_dir_callback_arg* arg = (fat_read_dir_callback_arg *) p;
                                                            ---------^
Versuch's mal so.

Autor: Stefan Kuhne (sk-ac)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

man ist man mal ein halbes Jahr weg von C und macht was ohne Pointer und 
dann passiert sowas.

Aber die "static_cast" Lösung werde ich auch nutzen.

Vielen Dank,
Stefan Kuhne

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Da muss man casten (sofern man sich sicher ist, dass
> die Zuweisung an sich in Ordnung ist)

Und das ist der Knackpunkt: Wenn man sich da sicher sein kann, dann kann 
man auch das API typsicher machen.

Die Frage ist: Warum ist der Pointer void* und nicht struct 
fat_read_dir_callback_arg* ?

Wenn es keinen schlagenden Grund gibt, könnte man drüber nachdenken, das 
zu ändern und in Zukunft ein C++-API mit sicherer Typprüfung zu haben. 
Für den, der das API benutzt, ist das ein Riesenvorteil.

Autor: Stefan Kuhne (sk-ac)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

tuppes schrieb:

> Wenn es keinen schlagenden Grund gibt, könnte man drüber nachdenken, das
> zu ändern und in Zukunft ein C++-API mit sicherer Typprüfung zu haben.
> Für den, der das API benutzt, ist das ein Riesenvorteil.


das dachte ich auch, nur wollte ich erstmal den Code durch den Compiler 
bekommen. Nicht das ich da arbeit reinstecke und dann hängt es irgendwo.

Stefan Kuhne

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tuppes schrieb:

> Die Frage ist: Warum ist der Pointer void* und nicht struct
> fat_read_dir_callback_arg* ?

Ist natürlich eine gute Frage.
Ich habs nicht angesprochen, weil das ganze danach stinkt, dass der void 
Pointer in Wirklichkeit auf ein Byte-Array zeigt. Könnte ein gelesener 
Sektor oder sowas sein.
Auch das 'callback' im Funktionsnamen hat mich stutzig gemacht. Ähnlich 
wie die void* beim qsort Callback. Und da ist dann auch schon das 
Stichwort, wie man so etwas typsicher hinkriegen kann: std:sort 
studieren.

Gerade bei I/O Sachen kommt man manchmal u so wilde Casts nicht rum.

Aber ich geb dir prinzipiell uneingeschränkt recht. Sobald void* im 
Spiel ist, sollte man zuerst danach trachten, den void* an sich 
loszuwerden.

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Auch das 'callback' im Funktionsnamen hat mich stutzig gemacht. Ähnlich
> wie die void* beim qsort Callback.

Bei qsort sollen ja gerade beliebige Arrays sortierbar sein, darum 
darf über den Grundtyp keine Angabe gemacht werden. qsort selber ist 
voll generisch, die Implementierung für bestimmte Typen geschieht allein 
in der zugehörigen compare-Funktion.

Auch im Fall oben gibt sich das API generisch, der Code ist es aber 
überhaupt nicht. Das ist ohne genaue Doku unbenutzbar.

Ein fast sicherer Indikator für einen solchen Fehler ist das Fehlen 
eines zum Pointer gehörenden size-Parameters - die Größe des Objekts ist 
also in Wahrheit doch vorgegeben.

Ich würde meinen, derjenige, der das C-API definiert hat, hat nicht 
richtig nachgedacht. Oder hatte nicht genug Erfahrung mit C, um die 
Fallstricke zu kennen. Jedenfalls ist jetzt der Zeitpunkt, das zumindest 
für C++-Programmierer zu korrigieren.

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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