Forum: Mikrocontroller und Digitale Elektronik Verständnissfrage -> C Code


von Marvin W. (Gast)


Lesenswert?

Hallo,

anbei mal ein Ausschnitt aus einem Code. Die Funktion soll wohl im 
großen und ganzen sich um serielle Daten kümmern.

An den Stellen wo ein Kommentar ist, verstehe ich den Sinn nicht ganz, 
kann mir vielleicht jemand auf die Sprünge helfen und evtl. verstehen 
was der Entwickler dieses Codes damit bezwecken wollte..
1
void sio_receive_and_store_job(struct sio_job_tabelle const *tab_ptr)
2
{
3
                UNION_32_8 unHelp;
4
                struct sio_job_tabelle jt;
5
                
6
                PGM_P p;
7
 
8
                void * pos;
9
 
10
                /*
11
                *             Spezieller Sinn???
12
                */
13
                p = (char *)tab_ptr;
14
                
15
                /*
16
                *             Schreibzugriff auf eine "const" Variable???
17
                */
18
                tab_ptr = &jt;
19
 
20
                do
21
                {
22
                               memcpy_P((void *)tab_ptr, p, sizeof(sio_job_tabelle));
23
 
24
                               if (tab_ptr->typ == 0) break;
25
                               
26
                               pos = tab_ptr->pos;
27
                               
28
                               if (ucSioBuffer[0])
29
                               {
30
                                 pos += sizeof(sio_slave_st) * (ucSioBuffer[0] -1);
31
                               }
32
 
33
                               switch(tab_ptr->typ)
34
                               {
35
                                 case 1: // char
36
                                               *((unsigned char *)pos) = (unsigned char)ucSioBuffer[uiBufferPos];
37
                                               uiBufferPos++;
38
                                 break;
39
                               } // endof switch(Datentyp)
40
                               
41
                p += sizeof(sio_job_tabelle);
42
 
43
                } while (1);
44
}

von Jim M. (turboj)


Lesenswert?

Der Code kopiert Daten vom Flash in den RAM (genauer: Variable auf dem 
Stack) um die besser verarbeiten zu können.

Das mit den Pointern (und wann was scheibbar ist und wo const stehen 
muss) übst Du besser nochmal.

Ach ja: Solche Klimmzüge sind nur für AVR nötig - weil AVR eine Havard 
Architektur ist, C aber eher für von-Neumann Architekturen gedacht ist.

Allerdings müsste ich auch z.B. auf Cortex-M3 Flash Daten erstmal ins 
RAM kopieren wenn ich sie ändern will.

von Nop (Gast)


Lesenswert?

Was hier passiert:

- p zeigt auf das Input-struct
- dann wird tab_ptr auf das lokale struct "jt" umgemapt
- dann wird das Input-struct in das lokale struct kopiert.

const ist übrigens nicht tab_ptr selber, sondern der Speicherbereich, 
auf den er zeigt.

Das hätte man auch einfacher haben können:
1
memcpy(&jt, tab_ptr, sizeof(jt));

Und das im Rest der Funktion mit jt statt mit tab_ptr referenzieren. Das 
wäre auch deswegen sauberer, weil tab_ptr als ein Pointer auf konstante 
Daten deklariert ist, und diesen Datentyp behält er auch dam dem 
Ummappen auf "jt".

von Marvin W. (Gast)


Lesenswert?

Nop schrieb:
> Was hier passiert:
> const ist übrigens nicht tab_ptr selber, sondern der Speicherbereich,
> auf den er zeigt.

Ok. Das heißt den Zeiger ansich kann ich verändern nur den 
Speicherbereich, sollte ich nicht verändern?
Was genau ist PGM_P für ein Macro?
Einfach ein Zeiger vom Typ char?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Keine Ahnung, was der Autor mit diesem Rumgecaste ausdrücken wollte...

Erst mal den Code aufräumen, was da steht geht auch ohne Casts:
1
void sio_receive_and_store_job (const struct sio_job_tabelle *tab_ptr)
2
{
3
    for (const struct sio_job_tabelle *p = tab_ptr; ; p++)
4
    {
5
        struct sio_job_tabelle jt;
6
7
        memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
8
9
        if (jt.typ == 0)
10
            break;
11
12
        uint8_t *pos = (uint8_t*) jt.pos;
13
14
        if (ucSioBuffer[0])
15
        {
16
            pos += sizeof (sio_slave_st) * (ucSioBuffer[0] - 1);
17
        }
18
19
        switch (jt.typ)
20
        {
21
            case 1: // char
22
                *pos = ucSioBuffer[uiBufferPos];
23
                uiBufferPos++;
24
                break;
25
        } // switch
26
                   
27
    } // for
28
}

Je nachdem, welchen Typ sio_job_tabelle.pos hat, fällt der letzte Cast 
auch weg.

Anstatt p könnte man auch tab_ptr verwenden, um durch den Speicher zu 
laufen, aber das ist Geschmackssache.

Unter Verwendung von __flash kann man's auch so schreiben:
1
void sio_receive_and_store_job (const __flash struct sio_job_tabelle *tab_ptr)
2
{
3
    for (const __flash struct sio_job_tabelle *p = tab_ptr; ; p++)
4
    {
5
        struct sio_job_tabelle jt = *p;
6
7
        if (jt.typ == 0)
8
            break;
9
        ...


Man kann auch direkt ohne lokale Kopie auf den Flash zugreifen:
1
    for (const __flash struct sio_job_tabelle *p = tab_ptr; ; p++)
2
    {
3
        if (p->typ == 0)
4
            break;
5
        ...

was es für den Fall .typ = 0 schneller mach da nicht der gesamte Struct 
gelesen wird.

Schließlich kann man sio_job_tabelle per Typedef definieren, so dass das 
lästige "struct" wegfällt:
1
typedef struct
2
{
3
   ...
4
} sio_job_tabelle;
5
6
void sio_receive_and_store_job (const __flash sio_job_tabelle *tab_ptr)
7
...

von Marvin W. (Gast)


Lesenswert?

Nop schrieb:
> Was hier passiert:
>
> - p zeigt auf das Input-struct

Wieso wird es auf char gecastet?

von Mutluit M. (mutluit)


Lesenswert?

Kannst noch weiter kürzen:

Den
  memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
kann man durch die folgende Zuweisung ersetzen:
  jt = *p;


:-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marvin W. schrieb:
> Nop schrieb:
>> Was hier passiert:
>>
>> - p zeigt auf das Input-struct

Nur anfangs, p wird in der while-Schleife verändert.
>
> Wieso wird es auf char gecastet?

Hack und unnötig, siehe mein Beispielcode.

Man kann zwar alles als char* abwickeln, aber p zeigt immer auf ein 
struct sio_job_tabelle das nur gelesen wird, d.h. der natürliche Typ für 
p wäre

const struct sio_job_tabelle* oder eben const __flash struct 
sio_job_tabelle*.

von Marvin W. (Gast)


Lesenswert?

Mutluit M. schrieb:
> Kannst noch weiter kürzen:
>
> Den
>   memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
> kann man durch die folgende Zuweisung ersetzen:
>   jt = *p;
>
> :-)

Sicher? Kopiert die Funktion mehrere Bytes?

von Mutluit M. (mutluit)


Lesenswert?

Marvin W. schrieb:
> Was genau ist PGM_P für ein Macro?
> Einfach ein Zeiger vom Typ char?

Das siehst du indem du dessen Definition dir anschaust
(entweder weiter oben im code oder in einem include-file...)

von Marvin W. (Gast)


Lesenswert?

Mutluit M. schrieb:
> Marvin W. schrieb:
> Was genau ist PGM_P für ein Macro?
> Einfach ein Zeiger vom Typ char?
>
> Das siehst du indem du dessen Definition dir anschaust
> (entweder weiter oben im code oder in einem include-file...)

Habe ich.. Dahinter verbirgt sich einfach nur "PGM_P". Ich war der 
Annahme das es irgendwas mit dem lesen aus dem flash zu tun hat..

von Mutluit M. (mutluit)


Lesenswert?

Marvin W. schrieb:
> Mutluit M. schrieb:
>> Marvin W. schrieb:
>> Was genau ist PGM_P für ein Macro?
>> Einfach ein Zeiger vom Typ char?
>>
>> Das siehst du indem du dessen Definition dir anschaust
>> (entweder weiter oben im code oder in einem include-file...)
>
> Habe ich.. Dahinter verbirgt sich einfach nur "PGM_P". Ich war der
> Annahme das es irgendwas mit dem lesen aus dem flash zu tun hat..

PGM_P müsste ein char* sein.

: Bearbeitet durch User
von Mutluit M. (mutluit)


Lesenswert?

Marvin W. schrieb:
> Mutluit M. schrieb:
>> Kannst noch weiter kürzen:
>>
>> Den
>>   memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
>> kann man durch die folgende Zuweisung ersetzen:
>>   jt = *p;
>>
>> :-)
>
> Sicher? Kopiert die Funktion mehrere Bytes?

So kannst du ganze Strukturen kopieren, egal wie gross :-)

von Marvin W. (Gast)


Lesenswert?

Wollte ich eigentlich schreiben :)).

Was ist mit..?

Mutluit M. schrieb:
Kannst noch weiter kürzen:
Den
memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
kann man durch die folgende Zuweisung ersetzen:
jt = *p;
:-)
Sicher? Kopiert die Funktion mehrere Bytes?

von Marvin W. (Gast)


Lesenswert?

Mutluit M. schrieb:
> Marvin W. schrieb:
> Mutluit M. schrieb:
> Kannst noch weiter kürzen:
>
> Den
>   memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
> kann man durch die folgende Zuweisung ersetzen:
>   jt = *p;
>
> :-)
>
> Sicher? Kopiert die Funktion mehrere Bytes?
>
> So kannst du ganze Strukturen kopieren, egal wie gross :-)

Wieso hat man dann die Funktion gewählt? Das ist doch deutlich 
performanter deine Idee...

von Mutluit M. (mutluit)


Lesenswert?

Marvin W. schrieb:
>> Den
>>   memcpy_P (&jt, p, sizeof (struct sio_job_tabelle));
>> kann man durch die folgende Zuweisung ersetzen:
>>   jt = *p;
>>
>> :-)
>>
>> Sicher? Kopiert die Funktion mehrere Bytes?
>>
>> So kannst du ganze Strukturen kopieren, egal wie gross :-)
>
> Wieso hat man dann die Funktion gewählt? Das ist doch deutlich
> performanter deine Idee...

Du musst wissen: es gibt viele dumme Programmierer da draussen... :-)

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Mutluit M. schrieb:
> PGM_P müsste ein char* sein

const char*

von Mutluit M. (mutluit)


Lesenswert?

Man müsste sich das Innere von memcpy_P() anschauen; es scheint etwas 
mehr zu machen als nur kopieren...
Die Zuweisung würde sich empfehlen anstelle von memcpy().

von Jan H. (janiiix3)


Lesenswert?

Mutluit M. schrieb:
> Man müsste sich das Innere von memcpy_P() anschauen; es scheint etwas
> mehr zu machen als nur kopieren...
> Die Zuweisung würde sich empfehlen anstelle von memcpy().

Wieso?

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Mutluit M. schrieb:
>> Man müsste sich das Innere von memcpy_P() anschauen; es scheint etwas
>> mehr zu machen als nur kopieren...
>> Die Zuweisung würde sich empfehlen anstelle von memcpy().
>
> Wieso?

Was meinst du mit wieso?

Nennt sich Objekt-Zuweisung, also wie in Mathe: A = B   usw...

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Wieso Du es empfehlen würdest...

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Wieso Du es empfehlen würdest...

Ist doch das naheliegendste.  :-)
Oder etwa nicht?

von Jan H. (janiiix3)


Lesenswert?

Mutluit M. schrieb:
> Jan H. schrieb:
>> Wieso Du es empfehlen würdest...
>
> Ist doch das naheliegendste.  :-)
> Oder etwa nicht?

Ich kenne die Funktion jetzt nicht.
Würde jedoch gerne wissen, wieso und was diese Funktion anders macht.
Ich glaube kaum das sie nur diese Zuweisung erledigt. Dafür bräuchte man 
nicht so viele Parameter übergeben?!

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Mutluit M. schrieb:
>> Jan H. schrieb:
>>> Wieso Du es empfehlen würdest...
>>
>> Ist doch das naheliegendste.  :-)
>> Oder etwa nicht?
>
> Ich kenne die Funktion jetzt nicht.
> Würde jedoch gerne wissen, wieso und was diese Funktion anders macht.
> Ich glaube kaum das sie nur diese Zuweisung erledigt. Dafür bräuchte man
> nicht so viele Parameter übergeben?!

Deine Neugier ist gut.
Aber dann befriedige deine Neugier doch einfach indem du nachschaust.
Den Code hast du ja von irgendwoher. Da müsste auch der Rest sein...
Ich meine, der Marvin müsste den Rest des Codes haben..

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Dann gehe ich mal davon aus, dass du es nicht weißt?

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Dann gehe ich mal davon aus, dass du es nicht weißt?

Die besagte Funktion hat die selbe Signatur, also die selben Parameter, 
wie das standard memcpy():

memcpy(ziel, quelle, laenge)

von Jan H. (janiiix3)


Lesenswert?

Mutluit M. schrieb:
> Jan H. schrieb:
>> Dann gehe ich mal davon aus, dass du es nicht weißt?
>
> Die besagte Funktion hat die selbe Signatur, also die selben Parameter,
> wie das standard memcpy():
>
> memcpy(ziel, quelle, laenge)

Du meintest weiter oben, die Zuweisung würde alleine reichen.. Jetzt 
schreibst Du was von memcpy.. Was denn nu?

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Mutluit M. schrieb:
>> Jan H. schrieb:
>>> Dann gehe ich mal davon aus, dass du es nicht weißt?
>>
>> Die besagte Funktion hat die selbe Signatur, also die selben Parameter,
>> wie das standard memcpy():
>>
>> memcpy(ziel, quelle, laenge)
>
> Du meintest weiter oben, die Zuweisung würde alleine reichen.. Jetzt
> schreibst Du was von memcpy.. Was denn nu?

Ich glaube du scheinst durcheinandergekommen zu sein.

Die besagte Funktion hat die selbe Signatur, also selbe Parameter und 
Rückgabetyp, wie das standard memcpy():
  memcpy(ziel, quelle, laenge)

Der anfänglich gepostete Code-Ausschnitt gehört doch nicht zum 
Standardumfang eines Compilers. Das ist vielmehr eine externe Library 
oder einfach eine Anwendung. Da ich den Code nicht kenne, kann ich auch 
nicht sagen was in memcpy_P() passiert.

Vlt. hast du nicht gemerkt dass es memcpy() gibt und memcpy_P().
Das erste ist in der Standardlibrary jedes C/C++-Compilers. Das 
memcpy_P() ist etwas selbstgeschriebenes (Code wurde nicht gepostet).

Statt memcpy() kann man die Zuweisung benutzen wenn es sich um nur ein 
Element handelt (also kein Array).

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Ich glaube eher weniger das diese Funktion selbst geschrieben wurde, sie 
ist Teil vom AVR siehe hier -> 
https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Für ein Element hätte ich es noch verstanden. Weiter oben wurde aber von 
der ganzen Struktur gesprochen bzw. geschrieben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marvin W. schrieb:
> Wieso hat man dann die Funktion gewählt?

Der Code wurde für avr-gcc älter alt v4.7 geschrieben oder der Autor war 
auf dem Wissensstand: __flash wurde erst in v4.7 eingeführt, während es 
memcpy_P als Teil der avr-libc seit Anbeginn der Zeit gibt.

Das Pointer-Target von p braucht diesen Qualifier um aus dem Flash zu 
lesen, ansonsten liest jt = *p aus dem RAM.

> Das ist doch deutlich performanter deine Idee...

Die Performance ist i.W. gleich.  memcpy_P macht einen Funktionsaufruf; 
die Struct-Zuweisung wird von avr-gcc inline expandiert.

Wenn man kleinen Code will, kann memcpy_P besser sein bei 
Mehrfachverwendung.  Der Overhead durch den Funktionsaufruf hält sich in 
Grenzen: weniger als 10 Ticks.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mutluit M. schrieb:
> Da ich den Code nicht kenne, kann ich auch nicht
> sagen was in memcpy_P() passiert.

http://nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html#gad92fa2ebe26e65fa424051047d21a0eb

von Mutluit M. (mutluit)


Lesenswert?

Jan H. schrieb:
> Ich glaube eher weniger das diese Funktion selbst geschrieben wurde, sie
> ist Teil vom AVR siehe hier ->
> https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Du musst wissen: C und C++ haben jeweils eine sog. Standardbibliothek.
Die o.g. Funktion memcpy_P() ist nicht Teil des Sprach-Standards.
Folglich muss es etwas anderes sein, also Teil einer anderen Bibliothek 
usw.

> Für ein Element hätte ich es noch verstanden. Weiter oben wurde aber von
> der ganzen Struktur gesprochen bzw. geschrieben.

Du muss Objekt-weise denken: eine Struktur ist ein Objekt (bzw. Klasse),
ebenso eine int-Variable usw...

: Bearbeitet durch User
von Mutluit M. (mutluit)


Lesenswert?

Johann L. schrieb:
> Mutluit M. schrieb:
>> Da ich den Code nicht kenne, kann ich auch nicht
>> sagen was in memcpy_P() passiert.
>
> 
http://nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html#gad92fa2ebe26e65fa424051047d21a0eb

Das sind anachronistische Besonderheiten des AVR.
Hat mit "normaler" C/C++-Programmierung nichts zu tun.

von Jan H. (janiiix3)


Lesenswert?

Mutluit M. schrieb:
> Jan H. schrieb:
>> Ich glaube eher weniger das diese Funktion selbst geschrieben wurde, sie
>> ist Teil vom AVR siehe hier ->
>> https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html
> Du muss Objekt-weise denken: eine Struktur ist ein Objekt (bzw. Klasse),
> ebenso eine int-Variable usw...

Das habe ich ehrlich gesagt noch nie ausprobiert. Damit wird also in C 
eine Struktur kopiert? Dann braucht man diese Funktion ja wirklich 
nicht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mutluit M. schrieb:
> Johann L. schrieb:
>> Mutluit M. schrieb:
>>> Da ich den Code nicht kenne, kann ich auch nicht
>>> sagen was in memcpy_P() passiert.
>>
>>
> 
http://nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html#gad92fa2ebe26e65fa424051047d21a0eb
>
> Das sind anachronistische Besonderheiten des AVR.
> Hat mit "normaler" C/C++-Programmierung nichts zu tun.

Hat auch keiner behauptet.

Und warum ist das anachronistisch?  Sind diese Features der avr-libc 
deprecated?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jan H. schrieb:
> Mutluit M. schrieb:
>> Jan H. schrieb:
>>> Ich glaube eher weniger das diese Funktion selbst geschrieben wurde, sie
>>> ist Teil vom AVR siehe hier ->
>>> https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html
>> Du muss Objekt-weise denken: eine Struktur ist ein Objekt (bzw. Klasse),
>> ebenso eine int-Variable usw...
>
> Das habe ich ehrlich gesagt noch nie ausprobiert. Damit wird also in C
> eine Struktur kopiert? Dann braucht man diese Funktion ja wirklich
> nicht.

Wie gesagt ist es keine Standard-Funktion, ebensowenig wie __flash 
Standard ist.  Und ohne __flash funktioniert so eine Zuweisung eben 
nicht.

von Mutluit M. (mutluit)


Lesenswert?

Also Leute, C sollte man wirklich nicht auf so einem AVR lernen! :-)
Lernt es auf dem normalen PC bzw. Laptop.

C ist im Grunde eine sehr einfach zu lernende Sprache.
Es ist so "rein" wie Mathematik.

: Bearbeitet durch User
von Jan H. (janiiix3)


Lesenswert?

Mutluit M. schrieb:
> Also Leute, C sollte man wirklich nicht auf so einem AVR lernen! :-)
> Lernt es auf dem normalen PC bzw. Laptop.
>
> C ist im Grunde eine sehr einfach zu lernende Sprache.
> Es ist so "rein" wie Mathematik.

Ich nehme es mir mal zu Herzen.

von nvidia (Gast)


Lesenswert?

Mutluit M. schrieb:
> C ist im Grunde eine sehr einfach zu lernende Sprache.
> Es ist so "rein" wie Mathematik.

Dann kennst du C höchstens oberflächlich.

von Mutluit M. (mutluit)


Lesenswert?

nvidia schrieb:
> Mutluit M. schrieb:
>> C ist im Grunde eine sehr einfach zu lernende Sprache.
>> Es ist so "rein" wie Mathematik.
>
> Dann kennst du C höchstens oberflächlich.

Wieso? Klappt's bei dir nicht so wie es soll?  :-)

von nvidia (Gast)


Lesenswert?

Mutluit M. schrieb:
> nvidia schrieb:
>> Mutluit M. schrieb:
>>> C ist im Grunde eine sehr einfach zu lernende Sprache.
>>> Es ist so "rein" wie Mathematik.
>>
>> Dann kennst du C höchstens oberflächlich.
>
> Wieso? Klappt's bei dir nicht so wie es soll?  :-)

Ne, im Gegensatz zu den Meisten habe ich mir den C-Standard mal 
angeguckt und darf bei dem meisten zu findenem Code irgendwelches 
schlecht definiertes Verhalten entdecken.

von Mutluit M. (mutluit)


Lesenswert?

Die, die sich für C interessieren sollten sich erstmal das in Ruhe 
reinziehen um ein Überblick zu bekommen und sich auch über die Historie 
informieren:
https://de.wikipedia.org/wiki/C_(Programmiersprache)

Da findet man auch diesen zutreffenden Satz:
"Abgesehen vom Mikrocontrollerbereich, wo eigene Dialekte existieren, 
sind die meisten aktuellen PC-/Server-Implementierungen eng an den 
Standard angelehnt [...]"

: Bearbeitet durch User
von Mutluit M. (mutluit)


Lesenswert?

nvidia schrieb:
> Mutluit M. schrieb:
>> nvidia schrieb:
>>> Mutluit M. schrieb:
>>>> C ist im Grunde eine sehr einfach zu lernende Sprache.
>>>> Es ist so "rein" wie Mathematik.
>>>
>>> Dann kennst du C höchstens oberflächlich.
>>
>> Wieso? Klappt's bei dir nicht so wie es soll?  :-)
>
> Ne, im Gegensatz zu den Meisten habe ich mir den C-Standard mal
> angeguckt und darf bei dem meisten zu findenem Code irgendwelches
> schlecht definiertes Verhalten entdecken.

Kannst du das nochmal in Deutsch schreiben, damit man es versteht? :-)

von nvidia (Gast)


Lesenswert?

Mutluit M. schrieb:
> nvidia schrieb:
>> Mutluit M. schrieb:
>>> nvidia schrieb:
>>>> Mutluit M. schrieb:
>>>>> C ist im Grunde eine sehr einfach zu lernende Sprache.
>>>>> Es ist so "rein" wie Mathematik.
>>>>
>>>> Dann kennst du C höchstens oberflächlich.
>>>
>>> Wieso? Klappt's bei dir nicht so wie es soll?  :-)
>>
>> Ne, im Gegensatz zu den Meisten habe ich mir den C-Standard mal
>> angeguckt und darf bei dem meisten zu findenem Code irgendwelches
>> schlecht definiertes Verhalten entdecken.
>
> Kannst du das nochmal in Deutsch schreiben, damit man es versteht? :-)

C ist so genial konzipiert, dass es kaum einer schafft, Code zu 
schreiben, der voll definiert ist und dabei auch noch garantiert* 
funktioniert.

*mal abgesehen von irgendwelchen numerischen Grenzen die in der Praxis 
nicht überschritten werden

von Mutluit M. (mutluit)


Lesenswert?

nvidia schrieb:
> Mutluit M. schrieb:
>> nvidia schrieb:
>>> Mutluit M. schrieb:
>>>> nvidia schrieb:
>>>>> Mutluit M. schrieb:
>>>>>> C ist im Grunde eine sehr einfach zu lernende Sprache.
>>>>>> Es ist so "rein" wie Mathematik.
>>>>>
>>>>> Dann kennst du C höchstens oberflächlich.
>>>>
>>>> Wieso? Klappt's bei dir nicht so wie es soll?  :-)
>>>
>>> Ne, im Gegensatz zu den Meisten habe ich mir den C-Standard mal
>>> angeguckt und darf bei dem meisten zu findenem Code irgendwelches
>>> schlecht definiertes Verhalten entdecken.
>>
>> Kannst du das nochmal in Deutsch schreiben, damit man es versteht? :-)
>
> C ist so genial konzipiert, dass es kaum einer schafft, Code zu
> schreiben, der voll definiert ist und dabei auch noch garantiert*
> funktioniert.

Dann mach dich mal schlau über Yacc & Co.:
https://en.wikipedia.org/wiki/Yacc
Die Sprache C ist wie ein Algorithmus in sich geschlossen definiert.
Es wird mit so einem Compiler-Compiler erstellt. Also quasi maschinell 
erzeugt.

von nvidia (Gast)


Lesenswert?

Mutluit M. schrieb:
> Dann mach dich mal schlau über Yacc & Co.:
> https://en.wikipedia.org/wiki/Yacc
> Die Sprache C ist wie ein Algorithmus in sich geschlossen definiert.
> Es wird mit so einem Compiler-Compiler erstellt. Also quasi maschinell
> erzeugt.

Sind dir Sachen wie "undefiniertes Verhalten" kein Begriff? Zu viel 
getrunken?

von Mutluit M. (mutluit)


Lesenswert?

nvidia schrieb:
> Mutluit M. schrieb:
>> Dann mach dich mal schlau über Yacc & Co.:
>> https://en.wikipedia.org/wiki/Yacc
>> Die Sprache C ist wie ein Algorithmus in sich geschlossen definiert.
>> Es wird mit so einem Compiler-Compiler erstellt. Also quasi maschinell
>> erzeugt.
>
> Sind dir Sachen wie "undefiniertes Verhalten" kein Begriff? Zu viel
> getrunken?

Ich habe überhaupt keine Probleme mit C oder C++. Im Gegenteil: ist 
alles logisch.

Wenn du mit C nicht klar kommst, dann liegt es mit 99.99999% 
Wahrscheinlichkeit an dir selbst :-)

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Johann L. schrieb:
> __flash

nur so am rand ...
der gcc qualifier __flash existiert nur in c und nicht in c++, also kann 
z.b. NICHT mit dem arduino framework verwendet werden.


mt

von Dirk B. (dirkb2)


Lesenswert?

Mutluit M. schrieb:
> Statt memcpy() kann man die Zuweisung benutzen wenn es sich um nur ein
> Element handelt (also kein Array).

Bei der Zuweisung kann es Probleme geben, wenn die Bereiche Miss-Aligned 
sind.

von Mutluit M. (mutluit)


Lesenswert?

Dirk B. schrieb:
> Mutluit M. schrieb:
>> Statt memcpy() kann man die Zuweisung benutzen wenn es sich um nur ein
>> Element handelt (also kein Array).
>
> Bei der Zuweisung kann es Probleme geben, wenn die Bereiche Miss-Aligned
> sind.

Das kann bei memcpy auch passieren.
Wenn der Bereich nicht aligned ist dann läuft es natürlich langsamer.
Aber in der Praxis unter normalen Bedingungen kann es nicht passieren,
wenn man nicht gerade #pragma pack(1) oder so definiert hat vor den 
Variablendefinitionen.

Ansonsten zeige mal ein Beispiel wo es Probleme machen würde.

: Bearbeitet durch User
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.