avr-gcc const und Pointer

Ich bin immer noch etwas verwirrt, was den avr-gcc betrifft :-(

schleierhaft :-(

Was genau bedeutet denn "const" bei Variablen-Deklarationen?

Konstanten in CONST liegen, und dieses Segment nachher im Flash Speicher

Was ist der Unterschied zwischen const int x = 1; und #define x 1

Klar, ein #define hat keine Adresse, aber wenn man die nie braucht, wie sollten dann Konstanten am besten deklariert werden, um Speicher zu sparen? (RAM und Code)

Was ist der Unterschied zwischen "const int" und "const char"? Lohnt es sich, kleine Werte als char oder byte zu deklarieren?

Wie werden String-Literale abgelegt? In etlichen Beispielen wird dort ein Puffer verwendet, in den so ein Literal kopiert wird, bevor der Puffer an weitere Funktionen als char*

Zugriffe auf Flash und RAM unterschiedlich sind, was aber gleich zur

Wie sind Pointer als Parameter implementiert? Zeigen solche Parameter (z.B. char *p) immer ins RAM, oder werden sie

Pointer zeigt?

Code schreibt?

DoDi

Reply to
Hans-Peter Diettrich
Loading thread data ...

Bitte was? ;-)

"const" bedeutet, dass man auf etwas nicht schreiben darf. Es bezeichnet nicht, wo es zu liegen hat. Es muss im gleichen Adressraum liegen wie eine Variable des gleichen Typs ohne "const" (bei AVR also nicht im Flash).

Wenn du den Optimizer des Compilers abgeschaltet hast kann die Variante mit #define besser sein. Ansonsten wird der Optimizer anschauen was du

ist.

ohne Angabe signed oder unsigned sein. "int" hat keine definierte Breite, mindestens 16 Bits und ist ohne Angabe signed.

Dazu wurden im anderen Thread Beispiele gepostet.

Ja.

Wenn ein Pointer ins Flash zeigen soll muss er ein entsprechendes Attribut verpasst bekommen. Siehe PROGMEM und _flash im anderen Thread bzw. hier in der Doku:

Reply to
Michael Baeuerle

Kann der avr-gcc denn jetzt schon die FLASH, EEPPROM und sram speicherbereiche unterscheiden? Soweit ich mich erinnere konnte er das nicht. Das gab dann schoen fehler wenn man eines der codebeispiele(fuer intels IAR compiler, glaub ich) aus den Atmel Appnotes compilieren wollte. Da kam dann halt was an der stelle im sram war(meist irgendein muell). Einfach den pointer zu dereferenzieren, das reichte nicht... Fuer alles eigene funktionen. Der C standard erlaubt soweit ich mich erinnern tu', das aendern von const variablen (ist wie in dem Piratenfilm eher eine Richtlinie).

Reply to
Johann Klammer

Beispiel:

------------------------------------------------------------------------ $ cat constant.c #include

void bla(void) { const char x = 1;

PORTB = x; }

------------------------------------------------------------------------

ergibt:

------------------------------------------------------------------------ $ avr-gcc -Os -mmcu=atmega128 -c -o constant constant.c $ avr-objdump -d constant

constant: file format elf32-avr

Disassembly of section .text:

00000000 : 0: 81 e0 ldi r24, 0x01 ; 1 2: 88 bb out 0x18, r24 ; 24 4: 08 95 ret

------------------------------------------------------------------------

Da ist also nichts im RAM gelandet.

Reply to
Michael Baeuerle

Keine Ahnung was du da meinst. Aber der gcc akzeptiert garantiert kein C++. Der g++ vielleicht.

Das ist der Hinweis an den Compiler, dass der Inhalt sich nicht

Wat? "traditionell"? Und was ist am avr-gcc da untraditionell? Das ist ein ganz normaler gcc. Ein CONST Segment ist mir auch unbekannt, ich nehme an du meinst .rodata oder .text?

Wenn du ein globales Array einfach nur const deklarierst, dann legst du

ist der einzige memory-mapped Speicherbereich eben das SRAM und da landet er dann. Das hat aber nichts mit dem avr-gcc zu tun, sondern mit dem C-Standard.

Musst du ins Assembly schauen. Kommt immer drauf an. Global oder

deklariert ist (daher ist ersteres zu bevorzugen). #defines sollte man eh nur einsetzen, wo es kein entsprechendes Sprachkonstrukt gibt.

von globalen Variablen oder von funktionslokalen?

Datentypen, siehe C-Standard. Ein char ist 8 Bit lang, ein int mindestens 16 Bit lang (auf dem AVR exakt 16 Bit).

Wenn du nichts weiter spezifizierst im RAM (wegen MMIO, s.o.).

Das sind 16 Bit Werte.

verwendest. Also wenn du einen char PROGMEM * (einen Pointer auf einen

(ohne Warnung!) uminterpretiert.

Ne.

Das hat alles mit dem avr-gcc nichts zu tun, sondern eher mit C

willst.

Johannes

--
>> Wo hattest Du das Beben nochmal GENAU vorhergesagt? 


Kosmologen: Die Geheim-Vorhersage.
Reply to
Johannes Bauer

Oder liegt diese Vorverarbeitung in der Arduino IDE (*.ino --> *.cpp)?

[...]

DoDi

Reply to
Hans-Peter Diettrich

Du redest jetzt nicht von avr-gcc, sondern von arduino, richtig?

anders" ist. Ein nackter avr-gcc will nur C, und avr-c++ nur C++.

24-Bit-Pointer, aber wenn Du arduino benutzt, wirst Du so einen kaum haben.

cu Michael

Reply to
Michael Schwingen

Michael Schwingen schrieb:

Ah ja, das ist ja schon mal ein Meilenstein auf meinem Einstieg :-)

DoDi

Reply to
Hans-Peter Diettrich

Am 23.03.2015 um 16:32 schrieb Michael Baeuerle:

Die GNU Coding Rules bevorzugen ja die Const-Variante da der Compiler

Allerdings funktioniert das:

const uint8_t bufSize=20; char buffer[bufSize];

not const". Hier muss man define nehmen.

Nebenbei meine ich auch das

typedef int counter_t; counter_t cnt; int x; ... cnt=x;

Robert

Reply to
Robert Loos

Robert Loos schrieb:

Deshalb ja meine Frage, ob man bei kleinen Konstanten besser byte nehmen sollte.

Bei Arduino funktioniert das mit const int bufSize = 100;

DoDi

Reply to
Hans-Peter Diettrich

werden) sollte das auch so funktionieren.

Ist doch auch (real) der gleiche Typ.

Reply to
Michael Baeuerle

Kann ich dir leider nicht sagen, ich programmiere AVRs immer direkt

Reply to
Michael Baeuerle

Am 24.03.2015 um 11:43 schrieb Michael Baeuerle: ...

Ja jetzt! Aber diese Zuweisung ist wahrscheinlich schon bei der

Reply to
Robert Loos

Robert Loos schrieb:

Von C darfst Du keine Typsicherheit erwarten, die auf Typnamen basiert. IMO vereinfachen typedefs nur dem Compiler das Parsen von Deklarationen,

bezeichnet.

auszugeben. Stell Dir nur mal vor, wieviele verschiedene

DoDi

Reply to
Hans-Peter Diettrich

Hallo Hans-Peter,

Hans-Peter Diettrich schrieb:

Fehlermeldungen auszuspucken, wenn man ein wirklich striktes Typsystem hat, noch ist das ein Problem, bei Aufruf eine Standardfunktion entweder selbst eine Typwandlung zu machen oder eben eine weitere Version dieser Standardfunktion zu erstellen, die nichts weiter macht, als die Typwandlung

Aufruf der Funktion hat.

Fehler vermeidet. Ein Sprache, die implizite Typwandlungen macht, ist kaputt.

Reply to
Martin Schoenbeck

Martin Schoenbeck schrieb:

Ein funktionierendes Typsystem erlaubt dem Compiler, erlaubte von unerlaubten Konvertierungen zu unterscheiden. Ein "unsigned" Wert kann

werden, da ist keine Fehlermeldung und nicht mal eine Warnung notwendig. Bei "signed" Werten wird es problematischer, die lassen sich an "unsigned" nicht zuweisen, wenn sie negativ sind. Aber auch da ist

Geschmack zu viele) implizite Umwandlungen gestattet :-]

DoDi

Reply to
Hans-Peter Diettrich

Am 24.03.2015 um 18:57 schrieb Hans-Peter Diettrich: ...

nicht mehr als bisher. Ich will Typumwandlungen ja nicht verbieten. Ich

itoa(cnt) eine Warnung absetzt und bei itoa((int)cnt) nicht, da die Typen kompatibel sind.

Robert

Reply to
Robert Loos

Hallo Hans-Peter,

Hans-Peter Diettrich schrieb:

einbauen. Das ist nicht das, was ich unter einem funktionierenden Typsystem verstehe, denn da definiere _ich_ als Entwickler, welche Eigenschaften ein

treffen.

grauenhaft.

ausgereiftes Typsystem hat, sondern wenn sie implizit konvertiert. Das

denke, niemand wird ernsthaft bestreiten wollen, jedenfalls vom Standpunkt

bequemer als Assembler.

Reply to
Martin Schoenbeck

definiertes Verhalten: | | A computation involving unsigned operands can never overflow, because | a result that cannot be represented by the resulting unsigned integer | type is reduced modulo the number that is one greater than the largest | value that can be represented by the resulting type.

Beispiel:

--------------------------------------- unsigned int a = UINT_MAX; unsigned int b = 0;

a = a + 1U; if (a == b) { ...

---------------------------------------

Reply to
Michael Baeuerle

Martin Schoenbeck schrieb:

Nein, das geht z.B. in Delphi (OPL) mit einem einzigen Datentyp: type TMyNumber = low..high; int8_t = -128..127; uint8_t = 0..$FF;

vordefinierten Datentyp festlegen, der dann irgendwann oder auf

dessen bekannte Grenzen einsetzen.

der Standardtyp (int, integer...) bei allen derzeitigen general-purpose Compilern bei 32 Bit. Bei Mikrocontrollern auch mal weniger, da wird das

beliebiger Genauigkeit.

DoDi

Reply to
Hans-Peter Diettrich

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.