-         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 24

Thema: explizite Typumwandlung

  1. #11
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Anzeige

    Praxistest und DIY Projekte
    Ich hab das jetzt mit dem VC (microsoft visual studio 2005) durchprobiert. Das sollte eigentlich schon auf GCC übertragbar sein.

    Vorweg:
    Code:
    int*  p = (char*)1000;           // geht garnicht, verständlich, ist ja auch ein widerspruch
    Klammervarianten:
    Code:
    int*    p  = (int*)1000;
    Code:
    
             (char*)p++;              // kennen wir schon, liefert p+4
             (int)p++;                   // ebenfalls
           p = (int*)(int)p++;      // ebenfalls
    
          ((char*)p)++;          // Mag er garnicht ==>    error C2105: '++' needs l-value
                                      
    



    Was geht ? (definitiv getestet)
    Code:
    int    tmp = (int)p;
       p = (int*)++temp;              
    
    Code:
    union { int* p;  int iP; } un;
          un.p = (int*)1000;
          un.iP++ ;     // (durch die union wird auch   int*p  mit-incrementiert


    und die grausliche Variante
    Code:
         p = (int*)((int)p + 1);



    Wie gesagt: getestet




    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  2. #12
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    04.08.2011
    Ort
    Hannover
    Beiträge
    164
    Sooo grauslich finde ich es gar nicht: Das hier (klick) hatte ich schon die ganze Zeit im Hinterkopf

    viele Grüße
    Andreas
    #define true ('/'/'/')
    #define false ('-'-'-')

  3. #13
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen

    Code:
    void uart_putc(char c)
    {
        /* ....... */
    }
    
    void uart_send(void* data, unsigned int size)
    {
       while(size--)
          uart_putc(*(char*)data++);   /* hier gibt es das Problem */
    }
    Was mir hier nicht klar ist:

    wozu ist eine Funktion gut, die Daten vom Typ "weißnichtsogenau", und das ist void, in eine andere Funktion stopft, die nur mit chars umgehen kann. Sollte data mal auf ints oder floats zeigen, kommt etweder Müll raus, oder es crasht. Und die Verwendung von void-Pointern führt nur dazu, daß einem der Compiler nicht mehr helfen kann, Fehler zu vermeiden.

    Es muß also heißen: uart_send(char* data, ... , und in Zukunft für jeden void* 5€ in die Kaffekasse (oder ersatzweise eine schriftliche Begründung von mindestens einer Seite, warum so etwas aus Gründen der Programmlogik wirklich nötig ist )!

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    zu PicNick
    Sorry, ich muss mich korrigieren, deine Zeile

    p = (int*) ((int)p + 1);

    funktioniert wirklich. Erhöht den Zeiger um 1 und nicht um 4.
    Hast Du völlig recht.


    zu Klebwax:

    wie soll man denn sonst eine universelle function schreiben ?
    ich möchte verschiedene Datentypen, Strukturen und ähnliches
    senden. Das Casten übernimmt bei mir die Funktion, ich brauche mich darum
    nicht mehr zu kümmern. Ich übergebe nur noch die Adresse und die Anzahl Bytes.

    int xx;

    struct
    char a,b,c,d;
    int e,f,g;<
    } st;


    und zudem finde ich daß:

    uart_send(&xx,sizeof(xx));
    uart_send(&st,sizeof(st));

    besser aussieht als:

    uart_send((char*)&xx,sizeof(xx));
    uart_send((char*)&st,sizeof(st));

    aber das ist sicher Geschmackssache. Funktionieren tut natürlich beides. Was die Sicherheit angeht,
    denke ich mal, nehmen sich beide Varianten nichts.
    anbei meine 5,-- Euro...

    Habt noch ein schönes Wochenende.

    Siro

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen
    wie soll man denn sonst eine universelle function schreiben ?
    ich möchte verschiedene Datentypen, Strukturen und ähnliches
    senden. Das Casten übernimmt bei mir die Funktion, ich brauche mich darum
    nicht mehr zu kümmern. Ich übergebe nur noch die Adresse und die Anzahl Bytes.

    int xx;

    struct
    char a,b,c,d;
    int e,f,g;<
    } st;


    und zudem finde ich daß:

    uart_send(&xx,sizeof(xx));
    uart_send(&st,sizeof(st));

    besser aussieht als:

    uart_send((char*)&xx,sizeof(xx));
    uart_send((char*)&st,sizeof(st));

    aber das ist sicher Geschmackssache. Funktionieren tut natürlich beides. Was die Sicherheit angeht,
    denke ich mal, nehmen sich beide Varianten nichts.
    anbei meine 5,-- Euro...
    Ich frag jetzt mal garnicht, ob du das ernst meinst. Was du willst, geht garnicht. Man kann weder ein Int noch eine Struktur einach so über die serielle Schnittstelle versenden. Dein Compiler hat schon gewußt, warum er deinen Code nicht bearbeiten wollte, und du ihn erst mit void* und casts mundtot machen musstest.

    Die 5€ kannst du behalten. Leg noch was drauf und kauf dir ein Buch über C und lerne. Und mach dir mal Gedanken über Strukturen, gepackt und ungepackt, auf verschiedenen CPUs mit 8 bis 64 Bit Wortbreite sowie Big und Little Endian und dann lerne was über robusten portablen Code und gewöhne dir einen solchen Stil an.


    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  6. #16
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich muss hier sicher keine Rechenschaft ablegen, aber zu Klebwax:
    ich möchte die Bytes so herausschicken, wie sie im Speicher stehen.
    Ob sie gepackt sind oder im Intel oder Motorola Format vorliegen ist in MEINEM Falle völlig unwichtig,
    Das ist lediglich ein Hexdump den ich zu Testzwecken herausschicke um SOFTWAREFEHLER AUFZUDECKEN.
    Deshalb finde ich deine voreilige Beurteilung unberechtigt negativ, satt kreativ...

    Dein Satz:
    Was du willst, geht garnicht. Man kann weder ein Int noch eine Struktur einach so über die serielle Schnittstelle versenden.
    ist in meinem Falle eine Falschaussage, denn es funktioniert ja einwandfrei.
    Siro

  7. #17
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Offenbar sind noch ein paar Leute ohne einen Schimmer, wie man wirklich professionelle Funktionen schreibt
    z.B


    void * memcpy ( void * destination, const void * source, size_t num );Das sind schon mal 15 €
    http://www.cplusplus.com/reference/clibrary/cstring/memcpy

    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #18
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von PicNick Beitrag anzeigen
    Offenbar sind noch ein paar Leute ohne einen Schimmer, wie man wirklich professionelle Funktionen schreibt
    z.B


    void * memcpy ( void * destination, const void * source, size_t num );Das sind schon mal 15 €
    http://www.cplusplus.com/reference/clibrary/cstring/memcpy

    Warum hast du dann nicht auch gleich das zweite Beispiel von Funktionen, für die soetwas wie ein void-Pointer überhaupt erfunden wurde, genannt: die Gruppe der Memory-Management-Funktionen. Die mehr als einseitige Begründung, wozu man so etwas braucht, findest du in der gängigen C-Literatur. Des gleichen findest du dort aber dort auch die Diskussionen, das eine richtige Programmiersprache Pointer, egal welcher Art, überhaupt nicht zulassen sollte. Offensichtlich haben Leute wie Wirth den Programmierern nicht zugetraut, vernüftig mit dem Instrument Pointer umzugehen.

    Um aber bei "professionelle Funktionen" zu bleiben, glaubst du ernsthaft, so etwas wie das beschriebene uart_send() würde einem professionellen Code Review standhalten ? Wie verhält sich die Funktion, bei verschiedenen Compileroptimierungen oder auch verschieden Compilern, wie auf CPUs mit unterschiedlichen Wortbreiten, wie auf einer CPU mit anderen Alignment-Regeln, und wie bei Big oder Little Endian Rechnern?

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  9. #19
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zum Thema void pointer hier ein Ausschnitt von learncpp.com: (hervorhebungen von mir)
    In general, it is a good idea to avoid using void pointers unless absolutely necessary, as they effectively allow you to avoid type checking. This allows you to inadvertently do things that make no sense, and the compiler won’t complain about it.

    .....

    However, very occasionally, you may still find a reasonable use for the void pointer. Just make sure there isn’t a better (safer) way to do the same thing using other language mechanisms first!
    Statt "Just make sure" hab ich gesagt, schreib eine ausführliche Begründung oder zahl in die Kaffekasse.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  10. #20
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    38
    Beiträge
    1.780
    Hmm, wie wärs mit folgendem Szenario:

    Eine Funktion deren Rückgabewert ein Funktionspointer auf sich selbst ist (bzw. ganz allgemein ein Pointer auf eine Funktion des gleichen Typs).
    Wenn du das ohne void* schaffst, gehört die Kaffeekasse dir


    Zugegeben, sowas braucht man eher selten, aber ich habe auch noch ein praxisrelevantes Beispiel für dich:

    Nehmen wir an du schreibst einen Low-Level Treiber für irgendeine Schnittstelle, sagen wir mal SPI. An dieser Schnittstelle können unterschiedlichste Geräte hängen, die wiederum eigene Treiber benötigen welche auf dem SPI Treiber aufsetzen. Bei solchen Treibern ist es üblich mit Callback-Funktionen zu arbeiten, damit das System nicht bei jeder Übertragung blockiert wird. Und aus eigener Erfahrung kann ich dir garantieren, daß du in einer Callback-Funktion mehr Informationen haben möchtest als nur ein Flag das dir sagt ob die Übertragung erfolgreich war oder nicht. Ein void-Pointer, der vom Low-Level Treiber einfach nur mitgeführt wird, erlaubt es dir beliebige Informationen an einen Job anzuhängen die dir dann in der Callback-Funktion wieder zur Verfügung stehen.
    So viele Treppen und so wenig Zeit!

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •