Better C99 -- ANSI/ISO-C-Standard

(Meine) Wunschvorstellung

© Helmut Schellong, Mai 2003, Mai 2006


C89, C99

Im Jahr 1989 wurde der erste ANSI-C-Standard verabschiedet.
Bereits in diesem Jahr gab es Compiler, die diesen Standard explizit beachtet/implementiert hatten.
Beispiel:  MS-C-386 V5.1 unter SCO-Unix 3.2.0, 1989 gekauft!

Im Jahr 1999 wurde der zweite C-Standard verabschiedet: C99
Jedoch bis jetzt, 2003, knapp vier Jahre nach Verabschiedung, gibt es
keinen C99-Compiler!
U.a. Microsoft und Borland haben offensichtlich nicht vor, C99 jemals zu unterstützen!

Warum ist das so?

Ich habe in den zurückliegenden etwa 7 Jahren die C-Szene beobachtet,
auf Webseiten, in Newsgroups und in Fachzeitschriften.
Daraus ist natürlich ein (Meinungs-)Bild entstanden:

Fazit:
Man ist enttäuscht von C99!
Man mag diesen Standard nicht!

Auch Dennis Ritchie, einer der beiden C-Erfinder, ist gewiß nicht begeistert von C99:
http://www.linuxworld.com/linuxworld/lw-2000-12/lw-12-ritchie.html
http://www.gotw.ca/publications/c_family_interview.htm
Kernighan/Ritchie tun sich auch schwer, eine dritte Ausgabe ihres Buches
Programmieren in C - ANSI-C99   [K&R].
zu schreiben. Bisher haben sie es nicht geschrieben!

Insbesondere habe ich den Eindruck gewonnen, daß die Compiler-Entwickler
C99 nicht mögen!:
  • Meiner Meinung nach steht das SCO-Betriebssystem OpenUnix8 am dichtesten
    vor einer 100%-igen C99-Implementation.
    Jedoch, was fehlt da noch?:  VLAs und _Complex!
  • Obwohl gcc seit langer Zeit gcc-VLAs beherrscht - was fehlt u.a. noch?:  C99-VLAs!
    Und die gcc-C99-Liste ändert sich kaum über die Zeit...
icc 7.1 von Intel hat zwar C99 praktisch zu 100% implementiert, aber das gilt zumindest
unter FreeBSD nur für die Compiler-Exe selbst, nicht für das Entwicklungssystem
mit den Libs und den Headern, Linker ...
Hier ist die Lage also anders herum wie bei OpenUnix8.

Im Library-Bereich hat C99 den Entwickern ein ganz dickes Ei gelegt - unbequem!
Bei der Sprache selbst hat sich nicht so viel geändert!
Aber gerade hinsichtlich des Letzteren hätten viele Programmierer mehr erwartet!
Die meisten C-Programmierer sind enttäuscht von C99!

Für wen?

Eine Programmiersprache hat den Zweck, daß Programmierer mit ihr programmieren!
Einen anderen Zweck gibt es nicht.

Folglich muß ein Standard primär für die Programmierer arbeiten!
Genau das hat C99 nicht in genügendem Umfang getan.
In weiten Bereichen hat man sogar gegen die Programmierer festgelegt!

In zweiter Linie müssen die Compiler-Entwickler bedient werden.

Drittens muß die Entwicklung bei den Prozessoren berücksichtigt werden.

Viertens muß die Stellung/Bedeutung der Sprache in der Welt gesichert werden.

Der C99-Standard jedoch dreht diese Prioritäten einfach um!

Bis vor C99 war C fast zu 100% eine echte Untermenge von C++.
Seit C99 ist das nicht mehr so.
Und weil das nicht mehr so ist, hätte man die Sprache C gemäß C99
noch viel stärker erweitern/verbessern sollen, entsprechend den Wünschen
und Vorstellungen einer Majorität der C-Programmierer!

Jedoch C99 wurde viel zu ängstlich festgelegt!

IMO

Die nachfolgende Wunschliste erfordert im wesentlichen nur Erweiterungen
in der Compiler-Exe, nicht aber im gesamten Entwicklungssystem.
Insofern sind diese Wünsche relativ einfach (einfacher) realisierbar.

  1. Warum keine Aufteilung in Basic-C und Full-C?
    (Wie bei PEARL z.B.)
  2. Warum wurde kein Compiler-Schalter gefordert, der die Prioritäten von &^|
    über die der Vergleichsoperatoren erhebt?
  3. Die neuen Schlüsselworte _Bool, _Complex, _Imaginary sind optisch bizarr!
    Es ist gar kein Problem, eventuell vorhandene Makros bool in _bool umzubenennen!
    Dann wäre _Bool eben bool - wie man es erwartet.
  4. Warum wurde bei _Bool nicht verlangt, daß bei einem _Bool-Array
    ein lückenloses Bitfeld angelegt werden muß?
    Der Wertebereich von [0;1] legt dies nahe. Besonders weil C im Embedded-Bereich
    extrem verbreitet ist, wo Bits massenhaft gebraucht werden und stets RAM-Mangel herrscht.
  5. _Complex und _Imaginary halte ich für relativ entbehrlich.
    Der Anteil aller Gleitkomma-Programme ist bereits verhältnismäßig gering, und die,
    die auch noch complex brauchen, erst recht.
    Anders gesagt:  Andere Dinge halte ich für wichtiger.
  6. Es ist nichts gegen das neue Schlüsselwort restrict einzuwenden, aber auch hier
    halte ich andere Dinge für wichtiger.
  7. Ein neuer Range-Operator  ..  hätte das Tor zu mehr Komfort aufstoßen können.
    Beispielsweise Arrays inhaltlich in allen Situationen manipulieren und festlegen zu können.
    von..bis   von..:anzahl , wobei  :  ein neuer unärer Operator ist.
  8. Warum wurde strlen() nicht ersetzt durch beispielsweise  lengthof ?
  9. Warum wurden strxxx() und memxxx() nicht mit Hilfe eines neuen Range-Operators
    und z.B. expliziter Array-Syntax ersetzt?
    Alle Standard-inline-Kandidaten sollten hier in Betracht gezogen werden.
  10. Warum wurde die vorhandene Verkettung von Stringliteralen:  "aabb"  "uy"
    nicht erweitert auf char-Array-Namen?
  11. Warum keinen vollen Satz von Rundungsfunktionen oder -makros?:
    round(), roundup(), rounddown(), roundzero().
  12. Warum kein logisches XOR  ^^  ?
  13. Warum keine Potenzier-Operation?  (a**3)
  14. Warum kein  a>2?a:b = x; ?
  15. Padding-Bits innerhalb der Bit-Repräsentation der Integer-Typen hätte ich niemals befürwortet!
    Wenn mal ein Prozessor-Hersteller meint, er müsse solche Bits in die User-Register einbauen,
    so bliebe er eben mit seinen ~500 absurden Exemplaren am Arsch der C-Welt allein.
  16. Warum kein Schlüsselwort  align ?
  17. Warum keine portablen Bitfelder? Das ist ganz leicht möglich! Tatsächlich!
    Gleiches gilt für Bitfeld-Arrays.
  18. Full-C:  Ein Typ  string  kann sinnvoll sein, mit Länge in den ersten 4 Bytes.
  19. Full-C:  switch mit Stringliteralen:  case "abc":
  20. void funktion(variadic);  void funktion(variadic a)  { ; }
    Mit Struktur-Übergabe durch den Compiler.
    Komponenten .argc, .argv, etc.  .argc kann auch 0 enthalten.
    Das hätte viele Vorteile gegenüber den Makros in <stdarg.h>, die aber beibehalten
    werden sollten.
  21. ...

Beispiele zu Obenstehendem:

[ align n ]
unsigned | signed
a:3,
b:4,
c:24,
d:1,
e:1,
f:18,
:5;

unsigned bfa[10]:4;
Portable Bitfelder, auch außerhalb von Strukturen, mit Kommaliste aufgereiht,
default=1st_field_is_maschine_aligned, Adresse auf erstes Feld möglich,
unsigned|signed geben nur die Signedness an, intern stets als uchar-Array angelegt,
vollkommen lückenlos, bit-padding nur am Ende.
Auch Bitfeld-Arrays, Bitfeld-Pointer, _Bool-Pointer.
int A[10];     //index 0..9
int B[1..10]; //index 1..10

b= foo(B[6..10]);

int foo(int b[4..8]) { /*...*/; }

A[6..]= B[4..6]; // wie memcpy()
A[..]= B[..]; // komplett
A[2..5]= 0; // wie memset()


char const a[]= "aaaaaaa";
unsigned char z[80];

z= a "//" a;
z[6..]= "." a;
z[8..] |= a;

.


Anhang

Wenige Tage nach Kreation dieser Seite:
Google zeigt nach Eingabe von "better c99" über 12000 Suchergebnisse, wobei diese Seite
an erster Stelle aufgeführt wird (international).

Wenn in Newsgroups erstmals über diese Seite informiert wird, gibt es jeweils einen kleinen Ansturm.

Das Thema dieser Seite ist folglich zweifellos interessant.



Bei den Padding-Bits stören mich die Konsequenzen, die sich daraus ergeben.
Beispielsweise die Trap-Repräsentationen, der Wegfall von Objekt-Korrespondenzen
in unions, usw.
Padding bits

Die Padding-Bits sind vollkommen undefiniert.
Es ist lediglich bekannt, daß sie vorhanden sein dürfen.

Und der Anwender/Programmierer kann nichts damit anfangen!
Padding-Bits sind etwa so anzusehen wie ein Prozessor-Status-Register.

Unter anderem wegen dieser Gegebenheiten halte ich es für absurd, daß solche
Bits in jedem Objekt (außer unsigned char) vorhanden sein dürfen.

In C-Newsgroups wird unendlich über Padding-Bits und die ungeahnten(?) Folgen ihrer
erlaubten Existenz -immer wieder neu- diskutiert und gestritten.
Man träumt schon fast von "Trap representation".
Schrecklich, schrecklich, furchtbar!


Bitfelder können auf indirekte Weise die Performance stark steigern!

Beispielsweise 22 _Bool-Objekte in einer Funktion können allesamt in einem einzigen
Register gehalten werden.
Beispielsweise mit  test  esi, $64  kann performant geprüft werden!

Das gilt teilweise auch für Bitfeld-Arrays, auch wenn dort die Bitfelder mehr als ein Bit haben.


Links