AVR-GCC: Welcher Zeichensatz?

#3250126
Lesenswert?

Hallo zusammen,
ich habe den Forenbeitrag ähnlichen Namens anno 2011 durchaus gefunden- 
dort wird die Frage aber nicht geklärt, sondern ein anders liegender 
Fehler gefunden.

Welchen Zeichensatz nutzt eigentlich AVR-GCC? Konkret ist im Quelltext 
unter AtmelStudio 6 ein "µ"-Zeichen als Integer "181" vom ATmega 
angezeigt worden. Nach:

http://en.wikipedia.org/wiki/Mu_(letter)

könnte das Unicoder oder UTF-8 sein. Auf den ersten Blick klingt beides 
für den kleinen AVR unglaubwürdig. Oder nutzt AVR-GCC einfach den 
Zeichensatz des Quellsystems (bei mir Windows 7), d.h. der Source-Code 
würde auf einem Linux-System anders kompiliert, wenn ich das Zeichen 
über die Tastatur eingebe und eine direkte Eingabe des Sonderzeichen als 
Escape-Sequenz mit Hex-Code des Zeichens wäre ratsam?

Viele Grüße
Nicolas
#3250136
Lesenswert?

Natürlich spielt der Zeichensatz eine Rolle. Wenn ich im Quelltext ein 
char mit dem Inhalt 'µ' erzeuge, ist es durchaus von Bedeutung, welchen 
Zahlenwert der Kompiler daraus macht - schließlich muß ich meinen 
Zeichensatz danach auslegen.

Eingebaut ist das Display nicht, aber angehängt. Und einen char kann ich 
ja durchaus als int anzeigen. Muß ich sogar, wenn ich den Zeichensatz 
entwerfe.
Gast #3250141
Lesenswert?

Nicolas S. schrieb:
> Natürlich spielt der Zeichensatz eine Rolle. Wenn ich im Quelltext ein
> char mit dem Inhalt 'µ' erzeuge, ist es durchaus von Bedeutung, welchen
> Zahlenwert der Kompiler daraus macht - schließlich muß ich meinen
> Zeichensatz danach auslegen.

nein macht es nicht. Er nimmt es so wie es kommt und wenn die es 
ausgibtst bekommst du es genauso zurück.

Das ist wie ein Tonbandgerät, dem ist auch die Sprache egal.

Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine 
rolle.
#3250155
Lesenswert?

Peter II schrieb:
> Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine
> rolle.

Die DOS-Erweiterung von ASCII ist es schonmal nicht. Da steht "mu" an 
Stelle 230 und an Stelle 181 ist ein Stück Rahmen.

Peter II schrieb:
> Das ist wie ein Tonbandgerät, dem ist auch die Sprache egal.

Der kleine AVR ist auch kein Tonbandgerät. Tonbandgeräte kenne ich noch. 
Die haben keinen Zeichensatz. Die haben nur <<  ■ || > >>, und das auch 
nur aufgedruckt.

Und wenn ich an einem Display einen Zeichensatz habe, der vom AVR 
erzeugt wird, ist es durchaus von Wichtigkeit, welches Zeichen im 
Quelltext zu welcher Zahl im char führen, ansonsten müßte ich nämlich 
jeden Text als Array eingeben. Will ich aber nicht. Mache ich über die 
Tastatur. Nur bei Sonderzeichen ist es interessant, ob das erzeugte 
Zeichen für jede Erzeugerplattform gleich ist. Ansonsten ist der 
Quelltext nicht portabel.

Deswegen ist für mich die Kenntnis des von AVR-GCC genutzten 
Zeichensatzes DOCH interessant. Ich finde es auch nicht schlimm, wenn 
andere das langweilig finden. Ich aber nicht.
Gast #3250165
Lesenswert?

Nicolas S. schrieb:
> Peter II schrieb:
>> Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine
>> rolle.
>
> Die DOS-Erweiterung von ASCII ist es schonmal nicht. Da steht "mu" an
> Stelle 230 und an Stelle 181 ist ein Stück Rahmen.

der µ steht aber nicht als code sondern als String und dort spielt der 
zeichensatz keine rolle. (er spielt auch im code keine Rolle, nur 
mekkert der compiler wenn du versucht eine Variabel mit nicht ASCCI 
zeichen anzulegen)

> Und wenn ich an einem Display einen Zeichensatz habe, der vom AVR
> erzeugt wird, ist es durchaus von Wichtigkeit, welches Zeichen im
> Quelltext zu welcher Zahl im char führen, ansonsten müßte ich nämlich
> jeden Text als Array eingeben. Will ich aber nicht.
Dabei hilft dir der zeichensatz nicht weiter. Der compieler macht 
überhaupt keine änderung von zeichen oder Berücksichtigt einen 
Zeichensatz.

Wenn dein Display eine 230 für ein zeichen will, dann musst du im 
Quelltext eine 230 hinschreiben egal wie das zeichen das aussieht.


Der Compieler ändere keine Zeichen, also spielt er Zeichensatz keine 
Rolle!
Gast #3250172
Lesenswert?

Der (avr-)gcc nutzt überhaupt keinen Zeichensatz. Der bekommt ein 
Source-File vorgesetzt, in dem er eine char-Konstante mit dem 
Integer-Wert 181 vorfindet. Welches Zeichen das ist, ist dem Compiler 
herzlich egal. Der übernimmt diese 181 einfach ins Hex-File.

Die Umwandlung des auf deinem Rechener-Bildschirm sichtbaren "µ" in des 
Char -Wert 181 macht nicht der Compiler, sondern der Editor. Und welchen 
Zeichensatz der benutzt, ist tatsächlich abhängig vom Betriebssystem, 
aber auch vom Editorprogramm selber.

Oliver
#3250174
Lesenswert?

Als C-Programmierer solltest du dir angewöhnen, dass du dich auf den 
originalen ASCII-Zeichensatz berufen darfst. 7-Bit - Kleinbuchstaben, 
Großbuchstaben, Ziffern und ein paar Sonderzeichen.
Alles darüber hinausgehende, insbesondere was bei gesetztem 8. Bit 
rauskommt, ist eine Frage von Gottvertrauen, Editor und hängt nicht 
zuletzt auch davon ab, was dein Ausgabegerät mit diesen Bytes macht.
#3250186
Lesenswert?

OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der 
AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt. (Oder 
präziser: Die Eingaben der Textdatei außerhalb des kleinen 
ASCII-Zeichensatzes gleich interpretiert).

Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von 
Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben. 
Tastatur wäre mir lieber gewesen. Hex wäre mir auch lieber gewesen. So 
sinkt eben stufenweise die Lesbarkeit - wenn's nicht besser geht, geht 
es nicht besser. Aber ob das wirklich nötig ist, wollte ich vorher 
geklärt wissen.

Danke für die Antworten
Nicolas
Gast #3250189
Lesenswert?

Nicolas S. schrieb:
> OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der
> AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt. (Oder
> präziser: Die Eingaben der Textdatei außerhalb des kleinen
> ASCII-Zeichensatzes gleich interpretiert).

immer nocht nicht verstanden! Der GCC nutzt keine Zeichensatz, er macht 
auch auf jeden System das gleiche. Nur wie dein Editor die Quelltext 
anzeigt kann anders sein.

> Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von
> Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben.
> Tastatur wäre mir lieber gewesen. Hex wäre mir auch lieber gewesen.

wo soll jetzt der unteschied zwischen Hex und Oktalcode sein?
#3250193
Lesenswert?

Nicolas S. schrieb:
> OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der
> AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt.

Das ganze hat nichts mit dem gcc zu tun!


Ein Compiler ist ein Programm welches eine Eingabedatei 'verwurschtet'. 
Welche Zeichen-Codes auch immer der Editor dort abgelegt hat, die werden 
vom Compiler benutzt.

Kann es sein, dass du noch nicht gemerkt hast, dass dein C-Programm, so 
wie du es mit dem Editor schreibst, auch nichts anderes als eine Abfolge 
von Code-Bytes ist? Dein Editor ist so freundlich und schreibt dir 
anstelle der Code Bytes, die zugehörigen Zeichen auf den Bildschirm. 
Aber Code ist Code. Eine C-Datei (oder überhaupt eine Text-Datei)
1
int main()
2
{
3
  return 0;
4
}
ist auf Dateiebene auch nichts anderes als eine Abfolge von ASCII Codes.

Der Compiler liest dieses und was auch immer an Codes in einem String 
vorkommt, das schreibt er so wie es ist, dann auch ins Programm hinein.

> Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von
> Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben.

Kann man sich organisieren. Zb. Mit Präprozessorhilfe und der Regel, 
dass der Compiler aufeinanderfolgende String-Literale zu einem einzigen 
Literal zusammenfassen muss.
Gast #3250198
Lesenswert?

Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung 
entspricht. Ich vermute der avr-gcc macht's nicht anders.
1
$ export LANG=de_DE.UTF-8
2
$ vi x.c
3
void main(void)
4
{
5
    char x[] = {"ABCµXYZ"};
6
}
7
$ /opt/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gcc -c x.c
8
$ hexdump -C x.o |grep ABC
9
00000060  00 00 00 00 41 42 43 c2  b5 58 59 5a 00 00 00 00  |....ABC..XYZ....|
10

11

12

13

14
$ export LANG=C
15
$ vi x.c
16
void main(void)
17
{
18
    char x[] = {"ABCµXYZ"};
19
}
20
$ /opt/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gcc -c x.c
21
$ hexdump -C x.o |grep ABC
22
00000060  41 42 43 b5 58 59 5a 00  00 47 43 43 3a 20 28 47  |ABC.XYZ..GCC: (G|
Gast #3250213
Lesenswert?

Stefan Ernst schrieb:
> Norbert schrieb:
>> Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung
>> entspricht.
>
> Nein!
> Der vi ist in deinem Beispiel derjenige, der einen Zeichensatz benutzt
> und für die Unterschiede verantwortlich ist.

Jo, war unklar ausgedrückt!
Ich wollte zum Ausdruck bringen, das wenn ich mich in einem UTF8 
Environment befinde, man zB kein µ in eine char Variable packen kann.

Da gibt's dann so etwas:
warning: multi-character character constant [-Wmultichar]

Aber du hast Recht, letztlich wird ein 'µ' je nach Env. verschieden im 
Sourcecode hinterlegt.
Gast #3250233
Lesenswert?

Stefan Ernst schrieb:
> Nein. Ein Octal-Code in einem String ist ein Backslash mit drei Ziffern
> dahinter. \265 ist völlig korrekt.

oh stimmt, bei 3 stellen kann man es so schreiben. Aber dann sollte auch 
hex genauso gehen.

> fprintf("\xb5C.net"); // geht nicht.

gcc liefert auch:

 warning: hex escape sequence out of range [enabled by default]

scheint mir irgendwie ein Bug zu sein. Denn

fprintf("\xb5 C.net");

funktioniert. Er will scheinbar mehr als 2 zeichen HEX einlesen.
Gast #3250243
Lesenswert?

Peter II schrieb:
> Stefan Ernst schrieb:
>> Nein. Ein Octal-Code in einem String ist ein Backslash mit drei Ziffern
>> dahinter. \265 ist völlig korrekt.
>
> oh stimmt, bei 3 stellen kann man es so schreiben. Aber dann sollte auch
> hex genauso gehen.
>
>> fprintf("\xb5C.net"); // geht nicht.
>
> gcc liefert auch:
>
>  warning: hex escape sequence out of range [enabled by default]
>
> scheint mir irgendwie ein Bug zu sein. Denn

Hängt damit zusammen das das 'C' noch als Teil des Hex Wertes angesehen 
wird.

Early termination funktioniert.

void main(void)
{
    char y[] = "\265C.net";
    char z[] = "\xb5""C.net";
}
#3250244
Lesenswert?

Karl Heinz Buchegger schrieb:
> Kann es sein, dass du noch nicht gemerkt hast, dass dein C-Programm, so
> wie du es mit dem Editor schreibst, auch nichts anderes als eine Abfolge
> von Code-Bytes ist? Dein Editor ist so freundlich und schreibt dir
> anstelle der Code Bytes, die zugehörigen Zeichen auf den Bildschirm.
> Aber Code ist Code. Eine C-Datei (oder überhaupt eine Text-Datei)int
> main()
> {
>   return 0;
> }
> ist auf Dateiebene auch nichts anderes als eine Abfolge von ASCII Codes.

Nein, unter dem Blickwinkel habe ich es noch nie betrachtet. Für mich 
wurde aus einem Binärwurst immer erst durch einen definierten 
Zeichensatz ein lesbarer Text. Also war ich bislang davon ausgegangen, 
daß ein Compiler/Präprozessor sich die Sachen erstmal wieder in eine 
Textebene legt, allein um Leerzeichen, Tabs und Zeilenumbrüche zu 
interpretieren. Kompilerbau hatten wir im Maschinenbaustudium nicht.

Sollte es heute abend nicht zu heiß zum nachdenken sein, lasse ich mir 
den Wurm, der sich durch binärzeugs frißt, und dabei binärkode zu 
erzeugt, nochmal in Ruhe durch den Kopf gehen.
Gast #3250262
Lesenswert?

Nicolas S. schrieb:
> Also war ich bislang davon ausgegangen,
> daß ein Compiler/Präprozessor sich die Sachen erstmal wieder in eine
> Textebene legt, allein um Leerzeichen, Tabs und Zeilenumbrüche zu
> interpretieren.

das braucht er keinen zeichensatz weile diese zeichen im ASCII 
feststehen. Er kann also einfach den den byte-wert vergleichen.
Persönliche Seite #3250583
Lesenswert?

Um zum Kern der Frage zurückzukommen:

AVR-Studio verwendet als Unterbau das "Microsoft Visual Studio", das 
wiederum verwendet im Editor üblicherweise die sogenannte 
"ANSI"-Codepage (CP1252) - die ist weitestgehend identisch mit ISO 
8859-1*. Das ist bei praktisch allen unter Windows arbeitenden 
Editoren der Standardfall. Neuere Visual-Studio-Varianten (und auch 
der windowseigene Primitiveditor Notepad) unterstützen jedoch auch 
UTF-8.

Die alten "DOS"-Codepages CP437 bzw. CP850 werden zur allgemeinen 
Verwirrung aber weiterhin verwendet - in Konsolenfenstern.

Das lässt sich umschalten (mode con cp select=1252), bringt aber nur 
dann befriedigende Ergebnisse, wenn das Konsolfenster nicht mit dem 
defaultmäßigen Pixelfont betrieben wird -- diese Relikt aus der vorderen 
Altsteinzeit nämlich legt die Zeichencodierung zusätzlich fest.


Dem Compiler ist es weitestgehend wurscht, was er im Quelltext findet - 
alle Zeichencodierungen haben als Schnittmenge den ASCII-Zeichensatz, 
und alle für C oder C++ syntaktisch relevanten Zeichen befinden sich in 
diesem ASCII-Zeichensatz. Wenn in Kommentaren oder Stringkonstanten 
Zeichen auftauchen, die nicht im ASCII-Zeichensatz liegen (Umlaute 
etc.), dann kann der Compiler wahlweise Fehlermeldungen ausgeben, oder 
die im Quelltext vorgefundenen Zeichen so, wie sie sind, durchreichen.

Steht da also in einer Stringkonstante etwas, was im verwendeten 
Texteditor aussieht wie ein µ, dann landet das in exakt derselben Form 
auch im erzeugten Binärcode.

Ob der diesen dann abarbeitende Prozessor die Stringkonstante wiederum 
in lesbarer Form z.B. auf einem LC-Display ausgibt, hängt vom 
Zeichensatz des LC-Displays ab -- da beispielsweise HD44780-Displays 
keine CP1252 verwenden, funktioniert das mit solchen Displays nicht, 
und eine Umsetzungstabelle ist vonnöten.


*) http://de.wikipedia.org/wiki/ISO_8859-1

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren