Discussion:
Syntax Wünsche zu integer Typen
(zu alt für eine Antwort)
Hermann Riemann
2017-02-16 10:44:45 UTC
Permalink
Raw Message
enum, bool, int und char sind zwar für den Maschinencode
gleich Typen, aber nicht für debugger und Programmverständnis.

Was C ab C99 einführte waren explizite Längenangaben bei
int wie in64_t.

Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.

Ebenso bei enum, bool und char.
bool x:1; würde ein Bit bei Variable x bedeuten.

Eine weitere Erweiterung wäre der offset.
z.B.:

struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.

Damit könnte man des layout compilerübergreifend festlegen,
ohne code Umgehungen zu programmieren.

Hermann
der sowas nicht gerne über einen selbstgebastelten
Präprozessor erledigen möchte.
--
http://www.hermann-riemann.de
Helmut Schellong
2017-02-16 13:04:51 UTC
Permalink
Raw Message
Post by Hermann Riemann
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Wieso 3 Byte + 3 Bit bei int.8.3?
Post by Hermann Riemann
Ebenso bei enum, bool und char.
bool x:1; würde ein Bit bei Variable x bedeuten.
Eine weitere Erweiterung wäre der offset.
struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.
Was bedeutet die erste 4?


Ich habe da schon 2003 geschrieben (10600 clicks):

http://www.schellong.de/better_c99.htm
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Hermann Riemann
2017-02-17 10:07:37 UTC
Permalink
Raw Message
Post by Helmut Schellong
Post by Hermann Riemann
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Wieso 3 Byte + 3 Bit bei int.8.3?
.8 würde 8 byte bedeuten ( oben eine Unachtsamkeit)
:3 die (zusätzlichen) 3 bit.
:3 ist aufwärtkompatibel zu C.
Post by Helmut Schellong
Post by Hermann Riemann
Ebenso bei enum, bool und char.
bool x:1; würde ein Bit bei Variable x bedeuten.
Eine weitere Erweiterung wäre der offset.
struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.
Was bedeutet die erste 4?
4 byte langer int typ wie oben.
Post by Helmut Schellong
http://www.schellong.de/better_c99.htm
1. Anmerkung ( vielleicht folgen weiter)

C muß aufwärtskompatibel bleiben.
Bei der Einführung neuer Namen sollte es nicht zu Konflikten kommen.
Es existieren viele alte C-Programme,
die ihre Entwickler, soweit zugreifbar, bereits kaum noch kennen.
Daher könnte C wie windows ( XP wegen noch funktionierende software)
auseinanderlaufen.

align würde bei mir wie folgt aussehen

int i.4 { align 1 };
1 heisst ein byte.

Und dann wäre auch noch das Wort mask interessant:

int i { mask 0x06 };
womit man auch definieren kann, *wo* die Zahl in einem
Bitfeld liegt.
Sonst kann es der compiler nach eigenen Ermessen anlegen.

( Ein compiler legt ein bit aus Rechenzeitgründen beim Ablauf
in ein oder 4 byte ab,
weil bei einem oi Maschinenbefehl
immer mindestens ein byte und nicht ein bit
in ein Register geladen bzw daraus gespeichert wird.
Adressen gehen byteweise..)

das mit { } ist wegen der Kompatibilität brauchbar.
An der stelle durfte bisher kein { stehen.
Also ist es aufwärtskompatibel.
Und damit machen neue Schlüsselwörter innerhalb
{} bei einer Deklaration bei alten Programmen
keine Probleme.

Bei den Definitionen von string und array
gibt es das Problem mit der Unterprogrammschnittstelle.
Sie benötigen einheitliche Deskriptoren.
Wenn das nicht stimmt, kann die Wirkung wie bei
falsch verwendeten pointer sein.

Hermann
der eher anderes vermisst wie { addr io } bei intel,
{ register } umd carry bit evetuell real zu handhaben
um etwa Maschinencode komplett nach C abzubilden.
( debugging Zwischenschritt )
--
http://www.hermann-riemann.de
Stefan Reuther
2017-02-17 17:30:40 UTC
Permalink
Raw Message
Post by Hermann Riemann
enum, bool, int und char sind zwar für den Maschinencode
gleich Typen, aber nicht für debugger und Programmverständnis.
Was C ab C99 einführte waren explizite Längenangaben bei
int wie in64_t.
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Das wäre, wenn überhaupt, dann int:27 (27 Bit). Vorausgesetzt, du
verstehst unter "Byte" eine Gruppe von 8 Bits, ein Oktett.
Post by Hermann Riemann
Eine weitere Erweiterung wäre der offset.
struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.
Damit könnte man des layout compilerübergreifend festlegen,
ohne code Umgehungen zu programmieren.
Du solltest zumindest mal definieren, was du eigentlich erreichen
willst. Einfach nur "Größe" und "Offset" reicht nicht aus, um alles, was
an Variabilität in einer Struktur sein könnte, auszudrücken.

Du bist ja eigentlich nicht erst seit gestern in der Programmiererei
unterwegs und solltest wenigstens wissen, dass es Big- und Little-Endian
gibt. Dann ist die Frage, ob man Elemente, die kleiner als eine
adressierbare Einheit sind, eher in den MSBs oder eher in den LSBs
anordnet. Prozessoren, die keine Oktette adressieren können, sind
selten, aber existieren. Außerdem sind verschiedene Formate für negative
Zahlen möglich (Zweierkomplement, Einerkomplement, Sign-Magnitude).
Musst du bei Elementen, die über weniger oder mehr als ein Speicherwort
gehen, einschränken, welche Buszyklen dafür generiert werden?

Also musst du dich eh einschränken. Willst du binäre Dateiformate lesen?
Willst du auf Memory-Mapped-Register zugreifen? Willst du einfach nur
Platz sparen?


Stefan
Patrick.Schluter
2017-02-17 19:03:32 UTC
Permalink
Raw Message
Post by Stefan Reuther
Post by Hermann Riemann
enum, bool, int und char sind zwar für den Maschinencode
gleich Typen, aber nicht für debugger und Programmverständnis.
Was C ab C99 einführte waren explizite Längenangaben bei
int wie in64_t.
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Das wäre, wenn überhaupt, dann int:27 (27 Bit). Vorausgesetzt, du
verstehst unter "Byte" eine Gruppe von 8 Bits, ein Oktett.
Post by Hermann Riemann
Eine weitere Erweiterung wäre der offset.
struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.
Damit könnte man des layout compilerübergreifend festlegen,
ohne code Umgehungen zu programmieren.
Du solltest zumindest mal definieren, was du eigentlich erreichen
willst. Einfach nur "Größe" und "Offset" reicht nicht aus, um alles, was
an Variabilität in einer Struktur sein könnte, auszudrücken.
Du bist ja eigentlich nicht erst seit gestern in der Programmiererei
unterwegs und solltest wenigstens wissen, dass es Big- und Little-Endian
gibt. Dann ist die Frage, ob man Elemente, die kleiner als eine
adressierbare Einheit sind, eher in den MSBs oder eher in den LSBs
anordnet. Prozessoren, die keine Oktette adressieren können, sind
selten, aber existieren. Außerdem sind verschiedene Formate für negative
Zahlen möglich (Zweierkomplement, Einerkomplement, Sign-Magnitude).
Musst du bei Elementen, die über weniger oder mehr als ein Speicherwort
gehen, einschränken, welche Buszyklen dafür generiert werden?
Also musst du dich eh einschränken. Willst du binäre Dateiformate lesen?
Willst du auf Memory-Mapped-Register zugreifen? Willst du einfach nur
Platz sparen?
Zumal einiges schon jetzt mit Bitfeldern machbar ist. Das es in einer
struct eingepackt ist ist meines Erachtens sogar ein Vorteil. Das
Typensystem des Compilers kann dann zwichen Typen hart Unterscheiden.

typedef struct myint {
unsigned u20:20;
:0; /* Garantiert das das nächste Feld im nächsten byte
landet */
unsigned u3:3;
} myint;


myint var = {.u20 = 20, .u3 = 1 };
myint var2 = var;

Schön ware es allerdings das Hermann Riemann aufmerksam bei der Wahl der
Terminologie wird. Byte und Bits sind sehr Unterschiedliche Sachen.
Ausserdem wäre ein Beispiel die die Vorteile seines Schemas demonstriert
willkommen. So wie es da steht sehe ich wirklich nichts dass nicht auch
schon mit Bitfeldern möglich ist.
Stefan's Einwände sind natürlich auch zu berücksichtigen (Portabilität
und so).
Hermann Riemann
2017-02-18 12:12:24 UTC
Permalink
Raw Message
Post by Stefan Reuther
Post by Hermann Riemann
enum, bool, int und char sind zwar für den Maschinencode
gleich Typen, aber nicht für debugger und Programmverständnis.
Was C ab C99 einführte waren explizite Längenangaben bei
int wie in64_t.
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Das wäre, wenn überhaupt, dann int:27 (27 Bit).
Nicht immer.
int.8 ist (untere Adresse) 4 oder 8 byte aligned.
int:27 bit aligned.
Post by Stefan Reuther
Vorausgesetzt, du
verstehst unter "Byte" eine Gruppe von 8 Bits, ein Oktett.
Allerdings. Nicht 8 bite byte kenne ich nur vor
alten nicht im Gebrauch befidlichen Rechner wie CDC3300 und
PDP8 (genauer IM6100)?
IBM360, 8080 und 6800.. hatten 8 bit.
Wie es bei Arm&Co ist, weiß ich noch nicht.
Post by Stefan Reuther
Post by Hermann Riemann
Eine weitere Erweiterung wäre der offset.
struct s { int i.4+4;};
was bedeuten würde das die Variable i 4 byte
hinter dem Strukturanfang liegt.
Damit könnte man des layout compilerübergreifend festlegen,
ohne code Umgehungen zu programmieren.
Du solltest zumindest mal definieren, was du eigentlich erreichen
willst. Einfach nur "Größe" und "Offset" reicht nicht aus, um alles, was
an Variabilität in einer Struktur sein könnte, auszudrücken.
struct etc. wird auch so auf Dateien gespeichert.
Wenn ich mit einem Programm schreibe,
und möchte das wieder so direkt einlesen
ohne dass mir ein compiler den struct anders anlegt ..

Wenn mir ein compiler z.B. mal struct stat
anders optimieren würde ..

Wenn ich Maschinencode (und pseudocode ..) auf struct abbilde
kann ich übersichtlicher als mit byte Masken programmieren.
Post by Stefan Reuther
Du bist ja eigentlich nicht erst seit gestern in der Programmiererei
unterwegs und solltest wenigstens wissen, dass es Big- und Little-Endian
gibt.
( Merker Tipp : Big wie IBM little wie intel.)
So etwas bekäme ich mit
union { int i; char x[4]}; und ein paar Befehle hin.
Probleme macht da eher die ASCII EBCDIC Konversion.
Weil ich ich weiss ob char ein Buchstabe oder eine Zahl sei soll.
Ich habe mal so geraten: >= ' ' oder '\n': Buchstabe Sonst Zahl.
Post by Stefan Reuther
Dann ist die Frage, ob man Elemente, die kleiner als eine
adressierbare Einheit sind, eher in den MSBs oder eher in den LSBs
anordnet.
Deswegen habe ich mask vorgeschlagen. beispiel:
int i mask 0x30.
( Bitweise wäre 0b..xx.... beser lesbar.
. für 0 x für 1. )
Post by Stefan Reuther
Prozessoren, die keine Oktette adressieren können, sind selten, aber existieren.
Das geht immer mit and und or Operationen.
Post by Stefan Reuther
Außerdem sind verschiedene Formate für negative
Zahlen möglich (Zweierkomplement, Einerkomplement, Sign-Magnitude).
Erinnerung: 2 Verschiedene Darstellungen für 0; +0 und -0.
Post by Stefan Reuther
Musst du bei Elementen, die über weniger oder mehr als ein Speicherwort
gehen, einschränken, welche Buszyklen dafür generiert werden?
Die Buszyklen spielen außer bei (SDL*) Pixelgrafik bei mir
derzeit eine Rolle.
Post by Stefan Reuther
Willst du binäre Dateiformate lesen?
Ja das möchte ich.
Auch schreiben und mit anderen z.B. Python Programme austauschen.
Post by Stefan Reuther
Willst du auf Memory-Mapped-Register zugreifen?
Was ist damit gemeint?
Der IO Speicherraum im RAM Speicherbereich wie bei Motorola 68000?
( Im Gegensatz zu intel mit eigenem Adressbereich?)

oder shared memory?
Post by Stefan Reuther
Willst du einfach nur Platz sparen?
Auf meinen intel Rechner momentan meist nicht.

Allerdings gibt es da cache Überlegungen,
weil Speicherzugriffe heutzutage ein Mehrfaches
wie opcode Ausführen bedeuten können.

Bei Arduino &Co kann das relevant werden.

Hermann
der derzeit nur privat propgrammiert. z.B.:
union pixel_ { int i; Uint32 u; struct { unsigned char b,g,r,a;};};
--
http://www.hermann-riemann.de
Stefan Reuther
2017-02-19 11:22:18 UTC
Permalink
Raw Message
Post by Hermann Riemann
Post by Stefan Reuther
Post by Hermann Riemann
Ich hätte gerne etwas wie int.8:3
was 3 byte + 3 bit bedeuten würde.
Das wäre, wenn überhaupt, dann int:27 (27 Bit).
Nicht immer.
int.8 ist (untere Adresse) 4 oder 8 byte aligned.
int:27 bit aligned.
Im jetzigen C-Standard ist das ja im Wesentlichen implementation defined...
Post by Hermann Riemann
Post by Stefan Reuther
Vorausgesetzt, du
verstehst unter "Byte" eine Gruppe von 8 Bits, ein Oktett.
Allerdings. Nicht 8 bite byte kenne ich nur vor
alten nicht im Gebrauch befidlichen Rechner wie CDC3300 und
PDP8 (genauer IM6100)?
Das gibt es auch bei DSPs, die man noch neu kaufen kann, und ich würde
damit rechnen, dass uns auch künftig noch neue Architekturen gerade aus
dem SIMD-Umfeld mit solchen Einschränkungen über den Weg laufen können.
Post by Hermann Riemann
Post by Stefan Reuther
Du solltest zumindest mal definieren, was du eigentlich erreichen
willst. Einfach nur "Größe" und "Offset" reicht nicht aus, um alles, was
an Variabilität in einer Struktur sein könnte, auszudrücken.
struct etc. wird auch so auf Dateien gespeichert.
Wenn ich mit einem Programm schreibe,
und möchte das wieder so direkt einlesen
ohne dass mir ein compiler den struct anders anlegt ..
Dann musst du auf Padding und Endianness Rücksicht nehmen, die in deiner
Syntax gar nicht vorkamen. Nicht als ganze Bytes darstellbare Bitbreiten
sind hingegen nicht so wichtig.
Post by Hermann Riemann
So etwas bekäme ich mit
union { int i; char x[4]}; und ein paar Befehle hin.
Eben. Da braucht es keine neue C-Syntax. (Mal davon abgesehen, dass eine
union eine eher halbgute Idee ist.)

Es gibt sogar schon eine Programmiersprache mit C-ähnlicher Syntax, die
es erlaubt, die "paar Befehle" so zu verpacken, dass sich die u.a. Union
bzw. Struct wie ein normaler int benimmt. Sie heißt C++. Skizze:

class BigEndianU32 {
public:
BigEndianU32(uint32_t i)
: a(i >> 24), b(i >> 16), c(i >> 8), d(i) { }
operator uint32_t() const
{ return (a<<24) + (b<<16) + (c<<8) + d; }
private:
uint8_t a, b, c, d;
};
Post by Hermann Riemann
Post by Stefan Reuther
Prozessoren, die keine Oktette adressieren können, sind selten, aber existieren.
Das geht immer mit and und or Operationen.
Das mag sein, ein C-Compiler bietet dir nur nicht immer einen Pointer,
der in der Lage ist, auf Oktette zu zeigen, wenn die kleinste nativ
adressierbare Einheit 24 oder 32 oder 1024 Bits hat.


Stefan

Loading...