Der Martin: C/C++ Befehl time(NULL) falscher Wert?

Beitrag lesen

Moin,

Also der Befehl radio.write() erwartet void* als Daten.

und das bedeutet jetzt was genau - so zusammenhanglos?

time_t stamp2 = time(NULL);

    uint8_t stamp[4];
    stamp[0] = (stamp2 >> 0)& 0xFF;
    stamp[1] = (stamp2 >> 8)& 0xFF;
    stamp[2] = (stamp2 >> 16)& 0xFF;
    stamp[3] = (stamp2 >> 24)& 0xFF;

Okay, das geht natürlich. Ist quasi die Holzhammer-Narkose. Einen eleganteren Weg hatte ich dir schon vorgeschlagen; ein anderer wäre eine union-Deklaration, so dass ein time_t und vier Bytes dieselben Adressen belegen:

union
 { time_t t;
   uint8  b[4];
 } stamp;

So kannst du denselben Speicherplatz einmal mit stamp.t als time-Wert ansprechen, und einmal mit stamp.b als Byte-Array.

//Allerdings:
    cout << "stamp: " << (unsigned long) *stamp << endl; // nur das erste Byte
    cout << "stamp: " << (unsigned int) stamp << endl; // nur Adresse
//Jetzt bekomm ich:
    radio.write( &stamp, 4); //sizeof(stamp)) ; // Also Adresse von stamp
    // nix gscheids

Nochmal: Der Ausdruck (unsigned long) *stamp nimmt die Basisadresse des Arrays als Zeiger auf uint8, dereferenziert diesen Zeiger und liest das erste Array-Element, und castet das dann nach unsigned long. Das ist dasselbe wie (unsigned long) stamp[0].
Der Ausdruck (unsigned int) stamp nimmt die Adresse des Arrays und castet die nach unsigned int. (Warum nimmst du hier nicht auch long?)
Und &stamp ist wieder nur die Adresse des Arrays, wobei der Adress-Operator & hier überflüssig ist (aber auch nicht schädlich).

uint8_t stamp[4];
*(unsigned long*)stamp = time(NULL);
cout << "stamp: " << *(unsigned long*)stamp << endl;

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

Prima: Der Compiler erkennt, dass du hier verschiedene Zeiger-Typen ineinander überführen willst und warnt, weil das meistens ein Fehler ist. Hier ist es dagegen Absicht.

So richtig, wie ich an den Speicherbereich bei Linux ran muss, weiß ich noch nicht?

Es gibt keinen Unterschied zwischen Linux und beispielsweise Windows in diesen Beispielen.

    data[x] = 0x01; x++;
    data[x] = analogValue & 0xFF; x++;
    data[x] = (analogValue >> 8) & 0xFF; x++;

Das geht noch etwas schöner, wenn man die Zuweisung und das Increment zusammenfasst:

    data[x++] = 0x01;
    data[x++] = analogValue & 0xFF;
    data[x++] = (analogValue >> 8) & 0xFF;

ERGÄNZUNG:
Wieso hantierst du eigentlich so umständlich mit einem time-Wert und dem Byte-Array herum? Wozu brauchst du das Array? Genügt nicht einfach sowas:

time_t stamp = time(NULL);
// weiterer Code ...
// weiterer Code ...
radio.write(&stamp, sizeof(stamp));

Denn eingangs hattest du noch darauf hingewiesen, dass radio.write() mit void* als Parameter deklariert ist, und der ist ja zu allen anderen Zeigertypen kompatibel.

Schöne Ostern noch,
 Martin