Discussion:
Wozu braucht man typedef wirklich?
(zu alt für eine Antwort)
Thomas Steinbach
2009-10-13 10:58:48 UTC
Permalink
Hallo,

kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?

Ich persoenlich finde es aber doch uebersichtlicher, wenn
ich genau weiss, welches Struktur hinter einem Datentyp
steht und nicht so ein "abstrahierter" Aliasnamen.... hmmm
Gerade wenn es mehrere verschachtelte Strukturen, bzw.
Datentypen sind.

Uebersehe ich da etwas? Gibt es irgendwelche anderen
Vorteile bei typedef, ausser der angeblich besseren Lesbarkeit?

Vor Jahren hatte mal ein Lehrer bei einer Progaufgabe
verlangt er will ein typedef sehen und kein struct. Weiss
aber nicht wieso er das wollte... Kann momentan auch
absolut keinen Vorteil sehen.

Wie schaut das bei anderen Sprachen aus, Iso-C++, ObjC, etc.?
Sind das das dort auch einfach nur Aliase?

Thomas
Rainer Weikusat
2009-10-13 11:53:16 UTC
Permalink
Post by Thomas Steinbach
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Wenn man solche aliase definieren moechte. ZB die 'exact width integer
types' (uint8_t, uint16_t etc) typedef-Namen. Ein anderes Beispiel
waeren die abstrakten Systemdatentypen in UNIX(*) zB pid_t fuer
'process ID'. Generell immer dann, wenn man eine zusaetzliche
'logische Abstraktion' zwischen Quellcode und 'C Datentypen' haben
moechte.
Markus Raab
2009-10-13 13:37:29 UTC
Permalink
Post by Thomas Steinbach
Vor Jahren hatte mal ein Lehrer bei einer Progaufgabe
verlangt er will ein typedef sehen und kein struct. Weiss
aber nicht wieso er das wollte... Kann momentan auch
absolut keinen Vorteil sehen.
Es sind halt 2 komplett verschiedene Sachen - es gibt natürlich Situationen
wo ein typedef richtig, ein neues struct aber unnütz ist (und bei dem Test
als falsch gewertet wird).

struct definiert eine neue Struktur, bzw. einen neuen Typen.

typedef hingegen führt nur einen neuen Namen für einen bestehenden Typen
ein. Wofür es benötigt wird? Für C ist es eine gute Frage, ich wüsste jetzt
auch nur das Argument "schönerer und kürzerer Name".

mfg Markus
Elmar Sack
2009-10-14 17:52:25 UTC
Permalink
Post by Markus Raab
struct definiert eine neue Struktur, bzw. einen neuen Typen.
typedef hingegen führt nur einen neuen Namen für einen bestehenden Typen
ein. Wofür es benötigt wird? Für C ist es eine gute Frage, ich wüsste
jetzt auch nur das Argument "schönerer und kürzerer Name".
(auf die Gefahr hin, mich hier zu blamieren) ich bin heilfroh, daß es das
typedef in C gibt. Wie der Name schon sagt, kann man damit neue Typen
definieren:

typedef int istatus;
typedef int imode;

und damit ist

void func_of_types(istatus status, imode mode);

erheblich sicherer als

void func_of_ints(int status, int mode);

Als ich meinen Code nach viel Ärger auf typedefs umgestellt hatte, bekam ich
große Augen, was sonst noch alles falsch implementiert war und nur durch
Zufall fehlerfrei lief.

Inzwischen habe ich mir auch angewöhnt, Funktionen wie init_istatus(),
is_valid_istatus() usw. zu benutzen. Macht das Leben erheblich einfacher.

Gruß
Elmar
Stefan Reuther
2009-10-14 19:06:03 UTC
Permalink
Post by Elmar Sack
Post by Markus Raab
typedef hingegen führt nur einen neuen Namen für einen bestehenden Typen
ein. Wofür es benötigt wird? Für C ist es eine gute Frage, ich wüsste
jetzt auch nur das Argument "schönerer und kürzerer Name".
(auf die Gefahr hin, mich hier zu blamieren) ich bin heilfroh, daß es das
typedef in C gibt. Wie der Name schon sagt, kann man damit neue Typen
typedef int istatus;
typedef int imode;
Das Problem in C ist, dass das eben leider keine neuen Typen werden,
sondern nur neue Namen für alte Typen.
Post by Elmar Sack
void func_of_types(istatus status, imode mode);
Das ist 100% identisch zu 'void func_of_types(int status, int mode);'.

Das ist natürlich kein Grund, deswegen auf typedefs zu verzichten. Die
typedefs erfüllen somit immer noch den Zweck "Dokumentation".

Man kann typedefs tatsächlich nutzen, um Typkorrektheit zu prüfen,
allerdings nur mit Trick: angenommen, man hat
typedef double length_t;
typedef double area_t;
length_t length_from_metres(double d);
length_t length_add(length_t a, length_t b);
area_t area_of_rect(length_t a, length_t b);
dann kann man z.B. durch temporäres Ersetzen der Typedefs durch
typedef struct length* length_t;
typedef struct area* area_t;
den Compiler anweisen, die beiden Typen tatsächlich als verschiedene
Typen aufzufassen. Compiliert man damit den Anwendungscode, wird der
Compiler dann alle Fälle anmeckern, wo der Nutzer Längen und Flächen
mischt oder direkt manipuliert anstatt die dazu zu verwendenden
Funktionen zu benutzen. (Die Implementation der Funktionen wird man
damit sicherlich nicht compiliert bekommen.) Ich nutze diesen Trick z.B.
in einem Audiocodec, um zu prüfen, dass ich nicht z.B. Fixpunktzahlen im
Format 1.15 mit welchen im Format 4.28 mische. Oh, und außerdem kann ich
mit den Typedefs das Ding von Fixpunkt (für den DSP) auf Floating Point
(für den PC) umstellen, ohne den eigentlichen Code anzufassen.

Natürlich könnte man die Werte gleich in Strukturen packen
typedef struct { double value; } length_t;
aber an sowas explodieren die Optimierer real existierender Compiler,
die gerne mal Hemmungen haben, "echte" Strukturen in Register zu packen.


Stefan
Elmar Sack
2009-10-15 17:25:24 UTC
Permalink
Post by Stefan Reuther
Natürlich könnte man die Werte gleich in Strukturen packen
typedef struct { double value; } length_t;
aber an sowas explodieren die Optimierer real existierender Compiler,
die gerne mal Hemmungen haben, "echte" Strukturen in Register zu packen.
Verzeihung, da war ich mal wieder zu schnell: genauso wie von dir
beschrieben, mache ich es auch! Ich arbeite deshalb ausschließlich bei
Übergaben mit Strukturen. Wie gut der Optimierer das packt, ist mir egal.

Elmar
Sebastian Waschik
2009-10-18 09:49:43 UTC
Permalink
Hallo,
Post by Stefan Reuther
Man kann typedefs tatsächlich nutzen, um Typkorrektheit zu prüfen,
allerdings nur mit Trick: angenommen, man hat
häufig hilft aber auch "splint". Wobei das dann gleich sehr pingelig
ist.

Viele Grüße
Sebastian Waschik
Thomas Richter
2009-10-13 13:45:30 UTC
Permalink
Post by Thomas Steinbach
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Richtig.
Post by Thomas Steinbach
Ich persoenlich finde es aber doch uebersichtlicher, wenn
ich genau weiss, welches Struktur hinter einem Datentyp
steht und nicht so ein "abstrahierter" Aliasnamen.... hmmm
Gerade wenn es mehrere verschachtelte Strukturen, bzw.
Datentypen sind.
Uebersehe ich da etwas? Gibt es irgendwelche anderen
Vorteile bei typedef, ausser der angeblich besseren Lesbarkeit?
Portabilität. Beispielsweise kannst Du in irgendeinem Header je nach vorhandener Architektur Dir die
Aliase korrekt zusammendefinieren, etwa Ganzzahltypen mit geeigneter Bitbreite.
Post by Thomas Steinbach
Vor Jahren hatte mal ein Lehrer bei einer Progaufgabe
verlangt er will ein typedef sehen und kein struct. Weiss
aber nicht wieso er das wollte... Kann momentan auch
absolut keinen Vorteil sehen.
Bei structs gibt es IMHO selten einen Vorteil. Wenn, dann wieder nur, um bestimmte systemabhängige Komponenten
hinter den typedef-Namen zu verbergen. "FILE" wäre etwa so ein Kandidat.
Post by Thomas Steinbach
Wie schaut das bei anderen Sprachen aus, Iso-C++, ObjC, etc.?
Bei C++ genauso. Objective C kenne ich nicht gut genug.

Grüße,
Thomas
Georg Bauhaus
2009-10-13 14:05:23 UTC
Permalink
Post by Thomas Steinbach
Hallo,
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
Außer in den genannten Fällen sind typedefs nützlich,
wenn man mit compiler-Besonderheiten zu tun hat, z.B.
mit eingebauten Funtionen. Ein typedef stimmt
wohl einen Typ mit dem compiler ab: Objekte des
Typs werden dann in den passenden Schaltkreisen
des compilers verarbeitet.

GNU Cs Attribute:
typedef double aType __attribute__(...);

Bei Intel ist das glaube ich ähnlich.
Alexander Bartolich
2009-10-13 14:09:42 UTC
Permalink
Post by Thomas Steinbach
[...]
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Gegenfrage:
Kannst du in leicht verständlichen Worten erklären, wozu man

const double PI = 3.14159265;

gebrauchen kann? Ist doch einfach einfach "nur" eine Art Alias, nicht?

--
Juergen Ilse
2009-10-13 15:07:08 UTC
Permalink
Hallo,
Post by Alexander Bartolich
Post by Thomas Steinbach
[...]
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Richtig. Man kann es nutzen, um Systemabhaengigkeiten dahinter zu verstecken
(z.B. bei Dingen wie "uint16_t", was ein Typ mit *genau* 16 Bit sein soll
und dann je nach Implementierung "short int" oder "int" oder ggfs. sogar
"char" sein koennte). Ebenso, wenn man Eigenschaften einer Struktur vor
dem Programmierer verbergen moechte (weil sie ohnehin system- oder imple-
mentierungs-abhaengig sind, z.B. "FILE", was eine systemabhaengige Srtruktur
ist, deren portable Benutzung aber nicht systemabhaengig ist ...).
Post by Alexander Bartolich
Kannst du in leicht verständlichen Worten erklären, wozu man
const double PI = 3.14159265;
gebrauchen kann? Ist doch einfach einfach "nur" eine Art Alias, nicht?
Nein, das ist eine Variable, bei der es illegal ist, ihren Wert an dieser
Stelle durch eine Anweisung zu aendern (der Compiler kann sie ggfs. auch
in einem "read-only" Speicherbereich anlegen). Ein "alias" fuer den Wert
wuerde man mit einem "#define PI 3.14159265" erhalten, aber das ist gegen-
ueber der oben stehenden "const" Deklaration etwas voellig anderes, denn
man kann bei der const-Variablen durchaus ihre Adresse bestimmen, von dem
"#define" Wert jedoch nicht.

Ueberhaupt sind die Faelle nicht vergleichbar, weil es sich einmal um Typen,
das andere mal um konkrete Daten handelt.

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Georg Bauhaus
2009-10-13 17:13:28 UTC
Permalink
Post by Thomas Steinbach
Hallo,
Post by Alexander Bartolich
Post by Thomas Steinbach
[...]
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Kannst du in leicht verständlichen Worten erklären, wozu man
const double PI = 3.14159265;
gebrauchen kann? Ist doch einfach einfach "nur" eine Art Alias, nicht?
Nein, das ist eine Variable, [...]
Ueberhaupt sind die Faelle nicht vergleichbar, weil es sich einmal um Typen,
das andere mal um konkrete Daten handelt.
Die Fälle (const decl vs typedef) scheinen mir durchaus vergleichbar.
In beiden Fällen geht es um Programmierer, die überlegen, wann, womit,
wofür, mit welchen Wirkungen ... sie Entitäten eines C-Programms
mit einem Namen versehen, wo dazu die Möglichkeit besteht.
In beiden Fällen gibts es Namen und ihre Folgen.

Die Fälle sind sogar formal vergleichbar, insofern "Name"
sowohl für typedef als auch für ein Objekt ein einschlägiges
Wort aus dem C-Standard ist.
(Oder vielmehr "Bezeichner" nach Übersetzung ins Englische,
man soll keine κορινθε vernachlässigen.)
Alexander Bartolich
2009-10-13 17:44:19 UTC
Permalink
Post by Juergen Ilse
[...]
Nein, das ist eine Variable, bei der es illegal ist, ihren Wert an dieser
Stelle durch eine Anweisung zu aendern (der Compiler kann sie ggfs. auch
in einem "read-only" Speicherbereich anlegen). Ein "alias" fuer den Wert
wuerde man mit einem "#define PI 3.14159265" erhalten, aber das ist gegen-
ueber der oben stehenden "const" Deklaration etwas voellig anderes, denn
man kann bei der const-Variablen durchaus ihre Adresse bestimmen, von dem
"#define" Wert jedoch nicht.
Ueberhaupt sind die Faelle nicht vergleichbar, weil es sich einmal um Typen,
das andere mal um konkrete Daten handelt.
Oh, Mann. Was bist denn du für einer. Also extra für dich eine
Einführung in die Grundlagen "sauberer" Programmierung.

Der folgende Code enthält Redundanz:

a1 = r1 * r1 * 3.14;
a2 = r2 * r2 * 3.14;

In beiden Zeilen ist die selbe Konstante *gemeint*, es wurden aber zwei
unabhängige Konstanten geschrieben. Ein Nachteil dieser Vorgehensweise
ist, dass es zu Inkonsistenzen kommen kann. Zum Beispiel wenn die erste
Zeile auf "3.141" verbessert wird, die zweite aber nicht.

Führt man eine zentrale Definition der Konstanten ein, z.B:

a1 = r1 * r1 * PI;
a2 = r2 * r2 * PI;

ergeben sich einige Vorteile:
- die zentrale Definition lässt sich mit weniger Aufwand ändern als
alle Verwendungen der Definition abzuklappern
- durch "sprechende" Name wird der Code selbsterklärend
- wenn andere Konstanten, die zufällig den selben Wert haben, einen
anderen sprechenden Name bekommen, ist die Zufälligkeit nicht mehr
(so) verwirrend

Dieses Grundprinzip sauberer Programmierung gilt nun nicht nur für
Fließkommazahlen vom Typ "double", sondern für alle Beziehungen im
Quellcode.

int x, y, i;
for(i = 0; i < ...; i++) {
y = f(x, i);
...

Sollt man z.B. eines Tages feststellen, dass Koordinaten wie "x"
und "y" auf einer 64-bit-Plattform auch einen 64-bit-Datentyp
verwenden sollten, dann freut man sich bestimmt, wenn der Code
separate, sprechende Bezeichner dafür hat.

coordinate_t x, y;
int i;
for(i = 0; i < ...; i++) {
y = f(x, i);
...

--
Markus Wichmann
2009-10-13 20:18:43 UTC
Permalink
Post by Thomas Steinbach
Hallo,
Post by Alexander Bartolich
Post by Thomas Steinbach
[...]
kann mir jemand in leicht verstaendlichen Worten
erklaeren wozu man typedef wirklich gebrauchen kann?
In reinem C ist es doch einfach "nur" eine Art alias, nicht?
Richtig. Man kann es nutzen, um Systemabhaengigkeiten dahinter zu verstecken
(z.B. bei Dingen wie "uint16_t", was ein Typ mit *genau* 16 Bit sein soll
und dann je nach Implementierung "short int" oder "int" oder ggfs. sogar
"char" sein koennte). Ebenso, wenn man Eigenschaften einer Struktur vor
dem Programmierer verbergen moechte (weil sie ohnehin system- oder imple-
mentierungs-abhaengig sind, z.B. "FILE", was eine systemabhaengige Srtruktur
ist, deren portable Benutzung aber nicht systemabhaengig ist ...).
typedef ist ebenso zur Abkürzung von Datentypen gedacht. Das ist vor
Allem bei Funktionspointertypen wichtig: Die POSIX-Funktion signal kann
man so hier:

void (*signal(int signum, void (*handler)(int)))(int);

oder so hier deklarieren:

typedef void (*sighandler_t)(int);
sighandler_t signal(int, sighandler_t);

(Wenn mir jetzt jemand sagen möchte, dass POSIX nicht Teil von C ist:
Danke, weiß ich selber, es ging mir um das Sprachbeispiel.)

Natürlich kann man sich mit viel Mühe auch durch die erste Deklaration
wurschteln, aber die zweite ist einfach lesbarer.

Letztlich läuft alles auf Lesbarkeit hinaus: Ich müsste nicht C
schreiben, wenn mir das egal wäre, denn ich könnte ja einfach im Kopf
kompilieren und alles in Assembler schreiben. Gut, ist nicht portabel,
aber sei es drum. Und wo wir dabei sind: Wieso Assembler benutzen, wenn
man mit der Prozessor-Doku und einem Hex-Editor den Code auch selbst
setzen kann? :-)
Post by Thomas Steinbach
Post by Alexander Bartolich
Kannst du in leicht verständlichen Worten erklären, wozu man
const double PI = 3.14159265;
gebrauchen kann? Ist doch einfach einfach "nur" eine Art Alias, nicht?
Ueberhaupt sind die Faelle nicht vergleichbar, weil es sich einmal um Typen,
das andere mal um konkrete Daten handelt.
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, sind die Programmzeilen

#define PI 3.14159265

und

const double PI = 3.14159265;

noch äquivalent: Sie weisen der Zeichenkette "3.14159265" eine kürzere
Zeichenkette als Bezeichner zu. Natürlich wirkt sich das "weiter unten"
anders aus, wenn man die Zeilen so weit konkretisiert hat, dass sie
nicht mehr äquivalent sind, aber so weit sind wir ja noch gar nicht.

Ähnliches macht auch

typedef void (*sighandler_t)(int);

Dieses Statement weist einer komplizierten Zeichenkette, die in diesem
Fall sogar zusammengesetzt ist, eine einfachere zu.
Post by Thomas Steinbach
Tschuess,
Tschö,
Markus
--
Nur weil ein Genie nix reißt, muß ja nun nicht gleich jeder Idiot
pausieren... Bully hats ja auch geschafft.
-- gUnter nanonüm in de.alt.anime
Juergen Ilse
2009-10-14 09:42:42 UTC
Permalink
Hallo,
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, sind die Programmzeilen
#define PI 3.14159265
und
const double PI = 3.14159265;
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
In der zweiten Form ist der Ausdruck &PI erlaubt, in der ersten Form eben
*nicht*. Der Grund ist, dass in der zweiten Form eben tatsaechlich eine
Speicherstelle reserviert ist, in der der Wert hinterlegt ist, waehrend die
erste Form lediglich zu einer stumpfen Textersetzung im Quelltext fuehrt.
Post by Markus Wichmann
Sie weisen der Zeichenkette "3.14159265" eine kürzere Zeichenkette als
Bezeichner zu.
Das tut die erste from, waehrend bei der zweiten eben Speicherplatz
reserviert wird, dort der Wert abgelegt wird, und PI in dem Fall den
an dieser Stelle im Speicher liegenden wert referenziert. Dass das
ein wirklicher Unterschied ist, erkennt man u.a. daran, dass man im
zweiten Fall die Adresse von PI bestimmen kann, im ersten jedoch nicht.
Post by Markus Wichmann
Natürlich wirkt sich das "weiter unten" anders aus, wenn man die Zeilen
so weit konkretisiert hat, dass sie nicht mehr äquivalent sind, aber so
weit sind wir ja noch gar nicht.
Da man in einem Fall die Adresse von PI bestimmen kann, im anderen Fall
jedoch nicht, gibt es (egal auf welcher Eben) einen recht deutlichen
semantischen Unterschied.

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Thomas Koller
2009-10-14 10:09:46 UTC
Permalink
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, sind die Programmzeilen
#define PI 3.14159265
und
const double PI = 3.14159265;
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir hier
sprechen" im posting oben nicht gelesen.
Post by Juergen Ilse
In der zweiten Form ist der Ausdruck &PI erlaubt, in der ersten Form eben
*nicht*. Der Grund ist, dass in der zweiten Form eben tatsaechlich eine
Speicherstelle reserviert ist, in der der Wert hinterlegt ist, waehrend die
erste Form lediglich zu einer stumpfen Textersetzung im Quelltext fuehrt.
Es ist allgemein bekannt das es im Detail solche Unterschiede gibt,
das hättest du jetzt nicht so umständlich extra beschreiben müssen.
(Aber ok, wenn man von der Usenetverwaltung ist ...)

Tom
Claus Reibenstein
2009-10-14 11:21:15 UTC
Permalink
Post by Thomas Koller
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, [...]
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir hier
sprechen" im posting oben nicht gelesen.
Ich weiß nicht, was Du unter "Abstraktionsebene" verstehst. Ich weiß
auch nicht, was Markus damit meint. Vielleicht definiert Ihr beiden erst
einmal diesen Begriff.

Gruß. Claus
Thomas Koller
2009-10-14 12:22:42 UTC
Permalink
Post by Claus Reibenstein
Post by Thomas Koller
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, [...]
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir hier
sprechen" im posting oben nicht gelesen.
Ich weiß nicht, was Du unter "Abstraktionsebene" verstehst. Ich weiß
auch nicht, was Markus damit meint. Vielleicht definiert Ihr beiden erst
einmal diesen Begriff.
Keine Definition, aber für dich vielleicht trotzdem ganz interessant:
http://www.doku.net/artikel/dieabstrak.htm

Tom
Markus Wichmann
2009-10-14 19:33:47 UTC
Permalink
Post by Claus Reibenstein
Post by Thomas Koller
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von
der wir hier sprechen, [...]
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir
hier sprechen" im posting oben nicht gelesen.
Ich weiß nicht, was Du unter "Abstraktionsebene" verstehst. Ich weiß
auch nicht, was Markus damit meint. Vielleicht definiert Ihr beiden
erst einmal diesen Begriff.
Gruß. Claus
Abstraktion ist ein Vorgang, bei dem ein Mensch bzw. ein Wesen mit
menschenähnlicher Intelligenz Eigenschaften von einem konkreten Objekt
entfernt, die in einem konkreten Zusammenhang auf eine bestimmte Art als
störend wirken.

Daraus trivialerweise folgend: Diese Abstraktion führt weder der
Compiler noch der C-Standard für dich durch, du musst schon selber
denken.

Eine Abstraktionsebene ist die Menge aller abstrakten Objekte, denen in
einem gegebenen Kontext vergleichbare Eigenschaften entfernt wurden oder
denen vergleichbare Eigenschaften übrig geblieben sind.

Natürlich weiß ich, dass ein Makro und eine
read-only-Variablen-Definition nicht das gleiche sind. Beispielsweise
ist nach

#define PI 3.1415

die Zeichenkette "2PI" ein gültiges Literal vom Typ double, auch wenn
sie etwas anderes enthält, als der Leser zunächst denken mag.

Nämliches mit einer read-only-Variable geht nicht.

Im Übrigen reservieren beide Varianten ungefähr gleich viel
Speicherplatz. Im Falle eines dummen Compilers braucht die Variante mit
dem Makro _mehr_ Speicherplatz, weil für jedes Vorkommen des Makros ein
Literal in die .rodata-Sektion kommt. Aber das ist OT.

Nein, wovon ich sprach, war dieser simple Vorgang: Einem Objekt wird ein
Name zu gewiesen. Hier ist von diesem Objekt fast alles abstrahiert,
sogar die Tatsache, dass es sich einmal um ein C-Objekt und bei dem
anderen um einen Typen handelt. Aber nichts anderes ging es. Auch

typedef int maeusekot;

weißt lediglich dem Typ "int" den Namen "maeusekot" zu. Dass int jetzt
ein atomarer Typ ist, tut ja nichts zur Sache. Natürlich ist das relativ
sinnfrei, wenn man nicht einen speziellen Zweck damit verfolgt. So kann
man auf Platformen mit den entsprechenden Eigenschaften natürlich

typedef int int32_t;

einführen. Auf anderen Maschienen gilt vielleicht auch

typedef long long int32_t;

oder auch

typedef char uint64_t;

Und gesetzt den Fall, dass jemand C auf einem UNIX schreibt, bei dem
schon das OS die von C geforderten Puffer bereitstellt, was hindert ihn
an

typedef int FILE;

?

Und auf die gleiche Weise ist

const double E = 2.71828;

genauso wie

#define E (2.71828)

auch "nur" die Definition eines Alias für ein Literal, wenn man einmal
die Details abstrahiert. Prinzipiell besteht doch überhaupt kein Bedarf
für dieses Alias, denn schließlich kann man überall, wo E steht, auch
2.7 einsetzen. Aber mit dem E versteht man die Formel vielleicht besser.

Tschö,
Markus
--
BASIC
Shoot yourself in the foot with a water pistol. On large systems,
continue until entire lower body is waterlogged.
Jens Schmidt
2009-10-14 21:51:02 UTC
Permalink
Post by Markus Wichmann
Natürlich weiß ich, dass ein Makro und eine
read-only-Variablen-Definition nicht das gleiche sind. Beispielsweise
ist nach
#define PI 3.1415
die Zeichenkette "2PI" ein gültiges Literal vom Typ double, auch wenn
sie etwas anderes enthält, als der Leser zunächst denken mag.
Implizites token pasting ist schon lange nicht mehr im Verhalten des
Preprozessors dabei. So ungefähr seit allem nach K&R.
--
Viele Grüße,
Jens Schmidt
Juergen Ilse
2009-10-15 02:41:34 UTC
Permalink
Hallo,
Post by Markus Wichmann
Natürlich weiß ich, dass ein Makro und eine
read-only-Variablen-Definition nicht das gleiche sind. Beispielsweise
ist nach
#define PI 3.1415
die Zeichenkette "2PI" ein gültiges Literal vom Typ double, auch wenn
sie etwas anderes enthält, als der Leser zunächst denken mag.
Mein gcc ist in diesem Punkt anderer Meinung (und ich ebenfalls) ...
Post by Markus Wichmann
Im Übrigen reservieren beide Varianten ungefähr gleich viel
Speicherplatz.
Falsch. Beim Makro wird nicht zwingend Speicherplatz reserviert, es kann
auch bei jeder Zuweisung im Maschinencode der Wert direkt im Maschinencode
stehen. Es sind schlicht voellig verschiedene Konstrukte, die nur im Falle
einer Zuweisung den selben Wert zuweisen. Hier von "auf der und jener Ab-
straktionsebene ist es das gleiche" herumzufaseln, zeugt meiner Ansicht
nach nur von einem falschen Verstaendnis der Sprache.
Post by Markus Wichmann
Nein, wovon ich sprach, war dieser simple Vorgang: Einem Objekt wird ein
Name zu gewiesen.
Im falle des Macros gibt es nicht "ein Objekt" dem ein Name zugewiesen
werden koennte (nein, wirklich nicht).
Post by Markus Wichmann
Und auf die gleiche Weise ist
const double E = 2.71828;
genauso wie
#define E (2.71828)
auch "nur" die Definition eines Alias für ein Literal, wenn man einmal
die Details abstrahiert.
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Schoen, aber bringt uns so etwas weiter? Nein, eher nicht. Es ist schlicht
Bloedsinn, in einer ernsthaften Diskussion um die Sprache C mittels Begriffen
wie "auf Abstraktionsebene sowieso" die real existierenden Unterschiede
zwischen grundverschiedenen Dingen einfach "wegdefinieren" zu wollen.
Post by Markus Wichmann
Prinzipiell besteht doch überhaupt kein Bedarf für dieses Alias, denn
schließlich kann man überall, wo E steht, auch 2.7 einsetzen.
Uberraschung: Bei der #define Variante passiert auch *exakt* *das* (ja, das
legt der Standard auch so fest: der Praeprozessor fuehrt diese Ersetzung
durch, bevor der Quelltext ueberhaupt zum ersten Mal fuer die Uebersetzung
angesehen wird).

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Thomas Koller
2009-10-15 06:25:22 UTC
Permalink
Post by Juergen Ilse
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Wenn man die Unterschiede nicht abstrahiert, ist mein rotes Fahrrad was
ganz anderes als dein blaues Fahrrad. Was sollte es uns bringen
wenn ich beides als das Gleiche (ein Fahrrad) betrachte?

Ein Fahrrad wird nicht zum Formel1-Rennwagen, aber beide
werden zu Fahrzeugen und sind dann in dem Sinn auch "das Gleiche".
Wenn ich es schaffe sowas zu abstrahieren, muss
ich nicht alles für Fahrrad, Rennwagen, PKW, LKW, ...
extra neu erfinden, weils ja unterschiedliche Sachen sind,
sondern kann vieles einfach übernehmen.

Oder auch beim Beispiel PI, auch nach dem define ist auf einer
tieferen Abstraktionsebene zwischen PI und 3.14 noch immer
ein Unterschied. Wie kommst dazu zu behaupten das wäre
das Gleiche?
Post by Juergen Ilse
Schoen, aber bringt uns so etwas weiter? Nein, eher nicht.
Doch, auf jeden Fall bringt uns das weiter. Eigentlich ist es gerade
beim Programmieren ganz wichtig dass man sich solche Abstraktionsstufen
wie mit deinem Beispiel Fahrrad und Rennwagen, schafft.
Wenn man nicht abstrahieren kann würden Programme sehr schnell
sehr unübersichtlich werden.
Post by Juergen Ilse
Es ist schlicht
Bloedsinn, in einer ernsthaften Diskussion um die Sprache C mittels Begriffen
wie "auf Abstraktionsebene sowieso" die real existierenden Unterschiede
zwischen grundverschiedenen Dingen einfach "wegdefinieren" zu wollen.
Du verwechselst "wegdefinieren" mit "wegabstrahieren". Um erfolgreich
programmieren zu können braucht es nicht nur die Fähigkeit die
Unterschiede erkennen zu können, sondern auch Gemeinsamkeiten.

Und das ist keineswegs Blödsinn, sondern in meinen Augen sogar ein
ganz zentraler Punkt. Zuerst muss man ein Problem abstrahieren um dann
wieder runter ins Detail gehen zu können, bis in die Sprach C runter
und noch weiter.

Du hast auf der erwähnten Ebene zum Beispiel nur die Vorgabe, dass du
die Zahl pi einheitlich verwenden willst. Gehst du dann in die
Ebene mplementierung von C runter, hast du mehrere Möglichkeiten diese
Abstraktion umzusetzen. Je nachdem für welche davon du dich entscheidest
hat das natürlich unterschiedliche Rahmenbedingungen die du kennen
und berücksichtigen solltest, aber für die obere Ebene sind solche
Details eher irrelevant.
Post by Juergen Ilse
Post by Markus Wichmann
Prinzipiell besteht doch überhaupt kein Bedarf für dieses Alias, denn
schließlich kann man überall, wo E steht, auch 2.7 einsetzen.
Uberraschung: Bei der #define Variante passiert auch *exakt* *das* (ja, das
legt der Standard auch so fest: der Praeprozessor fuehrt diese Ersetzung
durch, bevor der Quelltext ueberhaupt zum ersten Mal fuer die Uebersetzung
angesehen wird).
Warum sollte man das also tun, wenn man eh immer auch 2.7 schreiben
kann?

Tom
Claus Reibenstein
2009-10-15 09:13:33 UTC
Permalink
Post by Thomas Koller
Post by Juergen Ilse
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Da muss man aber schon sehr weit abstrahieren.
Post by Thomas Koller
Wenn man die Unterschiede nicht abstrahiert, ist mein rotes Fahrrad was
ganz anderes als dein blaues Fahrrad. Was sollte es uns bringen
wenn ich beides als das Gleiche (ein Fahrrad) betrachte?
Die Funktion eines Fahrrades ist von seiner Farbe unabhängig.
Post by Thomas Koller
Oder auch beim Beispiel PI
Gerade hier suche ich noch den gemeinsamen Kern zum typedef (bzw. eine
geeignete Abstraktionsebene, um in Eurer Nomenklatur zu bleiben).

Gruß. Claus
Thomas Koller
2009-10-15 09:26:54 UTC
Permalink
Post by Claus Reibenstein
Post by Thomas Koller
Post by Juergen Ilse
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Da muss man aber schon sehr weit abstrahieren.
Eigentlich nicht besonders weit. Sowas macht man in unserer Gesellschaft
alle naselang.
Post by Claus Reibenstein
Post by Thomas Koller
Wenn man die Unterschiede nicht abstrahiert, ist mein rotes Fahrrad was
ganz anderes als dein blaues Fahrrad. Was sollte es uns bringen
wenn ich beides als das Gleiche (ein Fahrrad) betrachte?
Die Funktion eines Fahrrades ist von seiner Farbe unabhängig.
ja und? Der Punkt ist, dass du vom konkreten Objekt Fahrrad
abstrahieren musst. Wenn du farbenblind bist, oder dir Farben
generell egal sind, dann nimm halt meinetwegen mein Mountainbike
vs. dein Straßenrad, da hast dann auch unterschiedliche Funktion,
trotzdem sind beides Fahrräder. Nur halt eine Stufe detaillierter
als die Unterscheidung Fahrrad und Auto.
Post by Claus Reibenstein
Post by Thomas Koller
Oder auch beim Beispiel PI
Gerade hier suche ich noch den gemeinsamen Kern zum typedef (bzw. eine
geeignete Abstraktionsebene, um in Eurer Nomenklatur zu bleiben).
Ich wünsche dir, dass du es schaffst, und du nicht auf ewig über
Detailprobleme und -lösungen nicht hinauskommst.

Tom
Claus Reibenstein
2009-10-15 14:34:17 UTC
Permalink
Post by Thomas Koller
Post by Claus Reibenstein
Post by Thomas Koller
Post by Juergen Ilse
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Da muss man aber schon sehr weit abstrahieren.
Eigentlich nicht besonders weit. Sowas macht man in unserer Gesellschaft
alle naselang.
Also mir ist bislang noch niemand begegnet, der Fahrrad und
Formel1-Rennwagen auf eine gemeinsame Ebene abstrahiert hätte oder
abstrahieren wollte.
Post by Thomas Koller
Post by Claus Reibenstein
Post by Thomas Koller
Wenn man die Unterschiede nicht abstrahiert, ist mein rotes Fahrrad was
ganz anderes als dein blaues Fahrrad. Was sollte es uns bringen
wenn ich beides als das Gleiche (ein Fahrrad) betrachte?
Die Funktion eines Fahrrades ist von seiner Farbe unabhängig.
ja und?
Wie "ja und"?
Post by Thomas Koller
Der Punkt ist, dass du vom konkreten Objekt Fahrrad
abstrahieren musst. Wenn du farbenblind bist, oder dir Farben
generell egal sind, dann nimm halt meinetwegen mein Mountainbike
vs. dein Straßenrad, da hast dann auch unterschiedliche Funktion,
Und folglich auch eine andere Abstraktionsebene.
Post by Thomas Koller
trotzdem sind beides Fahrräder. Nur halt eine Stufe detaillierter
als die Unterscheidung Fahrrad und Auto.
Das meinte ich mit "sehr weit abstrahieren".
Post by Thomas Koller
Post by Claus Reibenstein
Post by Thomas Koller
Oder auch beim Beispiel PI
Gerade hier suche ich noch den gemeinsamen Kern zum typedef (bzw. eine
geeignete Abstraktionsebene, um in Eurer Nomenklatur zu bleiben).
Ich wünsche dir, dass du es schaffst, und du nicht auf ewig über
Detailprobleme und -lösungen nicht hinauskommst.
Da gibt es für mich nichts zu "schaffen". Ich sehe keine geeignete
Ebene, und bislang konnte mir auch niemand eine aufzeigen.

Außerdem will _ich_ hier gar nichts abstrahieren.

Gruß. Claus
Thomas Koller
2009-10-15 15:18:54 UTC
Permalink
Post by Claus Reibenstein
Post by Thomas Koller
Post by Claus Reibenstein
Da muss man aber schon sehr weit abstrahieren.
Eigentlich nicht besonders weit. Sowas macht man in unserer Gesellschaft
alle naselang.
Also mir ist bislang noch niemand begegnet, der Fahrrad und
Formel1-Rennwagen auf eine gemeinsame Ebene abstrahiert hätte oder
abstrahieren wollte.
Nicht? Wo lebst du denn?
Zumindest hier bei mir hat das bei einer Spontanumfrage jeder auf
Anhieb verstanden, dass Fahrrad und Formel1-Rennwagen beides Fahrzeuge
sind.

Komisch wenn dir noch niemand begegnet ist, der eine Abstraktionsebene
"Fahrzeug" hätte brauchen können.
Post by Claus Reibenstein
Post by Thomas Koller
Post by Claus Reibenstein
Post by Thomas Koller
Wenn man die Unterschiede nicht abstrahiert, ist mein rotes Fahrrad was
ganz anderes als dein blaues Fahrrad. Was sollte es uns bringen
wenn ich beides als das Gleiche (ein Fahrrad) betrachte?
Die Funktion eines Fahrrades ist von seiner Farbe unabhängig.
ja und?
Wie "ja und"?
"ja und" im Sinn, das ist doch für das Beispiel irrelevant.
Post by Claus Reibenstein
Post by Thomas Koller
Der Punkt ist, dass du vom konkreten Objekt Fahrrad
abstrahieren musst. Wenn du farbenblind bist, oder dir Farben
generell egal sind, dann nimm halt meinetwegen mein Mountainbike
vs. dein Straßenrad, da hast dann auch unterschiedliche Funktion,
Und folglich auch eine andere Abstraktionsebene.
Richtig.
Post by Claus Reibenstein
Post by Thomas Koller
trotzdem sind beides Fahrräder. Nur halt eine Stufe detaillierter
als die Unterscheidung Fahrrad und Auto.
Das meinte ich mit "sehr weit abstrahieren".
Wie gesagt, wenn das für dich schon "sehr weit" ist, dann ist es
mit deiner Fähigkeit zum abstrahieren vermutlich nicht so weit her. :-)
Aber wir können uns gern darauf einigen dass "Fahrzeug" eine weitere
Abstraktionsebene ist als "Fahrrad". "sehr" ist ohnehin ein sehr
relativer Begriff. ;-)
Post by Claus Reibenstein
Post by Thomas Koller
Post by Claus Reibenstein
Post by Thomas Koller
Oder auch beim Beispiel PI
Gerade hier suche ich noch den gemeinsamen Kern zum typedef (bzw. eine
geeignete Abstraktionsebene, um in Eurer Nomenklatur zu bleiben).
Ich wünsche dir, dass du es schaffst, und du nicht auf ewig über
Detailprobleme und -lösungen nicht hinauskommst.
Da gibt es für mich nichts zu "schaffen".
Nun, laut deiner Aussage suchst du sie, findest diese Abstraktionsebene
aber nicht. Wenn dir der Begriff "schaffen" dafür nicht passt kannst
du gern einen besseren vorschlagen.
Post by Claus Reibenstein
Ich sehe keine geeignete
Ebene, und bislang konnte mir auch niemand eine aufzeigen.
Außerdem will _ich_ hier gar nichts abstrahieren.
Du nicht, aber der OP. Wenn du seine Abstraktion nicht schaffst, dann
macht es wenig Sinn wenn du an seiner Diskussion teilnimmst, da du
dann an den anderen Diskussionsteilnehmern vorbeireden wirst.

Tom
U. v. Bassewitz
2009-10-15 17:40:29 UTC
Permalink
Post by Claus Reibenstein
Also mir ist bislang noch niemand begegnet, der Fahrrad und
Formel1-Rennwagen auf eine gemeinsame Ebene abstrahiert hätte oder
abstrahieren wollte.
http://de.wikipedia.org/wiki/Fahrzeug
Post by Claus Reibenstein
Post by Thomas Koller
Post by Claus Reibenstein
Die Funktion eines Fahrrades ist von seiner Farbe unabhängig.
ja und?
Wie "ja und"?
Genau das ist die Abstraktion. "Rotes Fahrrad" und "blaues Fahrrad" wurden
als "Fahrrad" abstrahiert, indem Eigenschaften weggelassen wurden, die
für das Verständnis eines bestimmten Sachverhalt nicht benötigt werden.
Post by Claus Reibenstein
Da gibt es für mich nichts zu "schaffen". Ich sehe keine geeignete
Ebene, und bislang konnte mir auch niemand eine aufzeigen.
Außerdem will _ich_ hier gar nichts abstrahieren.
Abstrahieren ist was ganz normales, das tust Du permanent. Bloss hier
nicht, weil Du sonst zugeben müsstest, Unrecht zu haben:-)

Gruß


Uz (seit langem mal wieder d.c.l.c lesend und sehr erheitert)
--
Ullrich von Bassewitz ***@spamtrap.musoftware.de
19:27:52 up 2 days, 22:01, 13 users, load average: 0.01, 0.07, 0.13
Claus Reibenstein
2009-10-15 20:33:54 UTC
Permalink
Post by U. v. Bassewitz
Abstrahieren ist was ganz normales, das tust Du permanent. Bloss hier
nicht, weil Du sonst zugeben müsstest, Unrecht zu haben:-)
Womit soll ich Unrecht haben?

Gruß. Claus
U. v. Bassewitz
2009-10-15 20:46:44 UTC
Permalink
Post by Claus Reibenstein
Post by U. v. Bassewitz
Abstrahieren ist was ganz normales, das tust Du permanent. Bloss hier
nicht, weil Du sonst zugeben müsstest, Unrecht zu haben:-)
Womit soll ich Unrecht haben?
Schon gut, ist klar. Wie wir alle wissen haben im Usenet immer alle
Recht:-)

Ich war bloss nach längerer Zeit mal wieder in die Gruppe reingestolpert
und äusserst amüsiert über die Diskussion. Ich hätte mir den Kommentar
verkneifen sollen. Bin auch schon wieder weg. Nix für ungut.

Gruß


Uz



P.S.: Das mit dem Fahrzeug hast Du aber jetzt verstanden, oder? :-)
--
Ullrich von Bassewitz ***@spamtrap.musoftware.de
22:35:50 up 3 days, 1:09, 13 users, load average: 0.22, 0.15, 0.15
Georg Bauhaus
2009-10-15 09:53:52 UTC
Permalink
Post by Thomas Steinbach
Hallo,
Post by Markus Wichmann
Natürlich weiß ich, dass ein Makro und eine
read-only-Variablen-Definition nicht das gleiche sind. Beispielsweise
ist nach
#define PI 3.1415
die Zeichenkette "2PI" ein gültiges Literal vom Typ double, auch wenn
sie etwas anderes enthält, als der Leser zunächst denken mag.
Mein gcc ist in diesem Punkt anderer Meinung (und ich ebenfalls) ...
Post by Markus Wichmann
Im Übrigen reservieren beide Varianten ungefähr gleich viel
Speicherplatz.
Hier von "auf der und jener Ab-
straktionsebene ist es das gleiche" herumzufaseln, zeugt meiner Ansicht
nach nur von einem falschen Verstaendnis der Sprache.
Von welcher falsch verstandenen Sprache sprichst du,
wenn du eine Definition von "Abstraktionsebene" Gefasel nennst?

Die formal angebbaren C-Regeln würden mich interessieren,
auf die du Strukturvalidität und Autorität deines Urteilsspruchs
stützt.

Die Begriffe, die in elementarerer nicht-C-sondern-Mensch-Semantik
verwendet werden, um Bedeutungen von Verstehens-bezogenen Fachbegriffen
einigermaßen festzugen ("Wat is ene Abstraktionsebene?"), sind,
nehme ich nach Lesen des Weiteren an, dir etwas weniger
geläufig als Markus?
Post by Thomas Steinbach
Wenn man die Unterschiede abstrahiert, ist ein Fahrrad ein Formel1-Rennwagen.
Schoen, aber bringt uns so etwas weiter? Nein, eher nicht.
Doch, das Beispiel von Fahrrad und Formel-1-Rennwagen
bringt weiter, in angebbarer Weise: Beide sind Fahrzeuge, für
die jetzt offenbar drei verstehbare Namen genannt sind.
Jeder der Bezeichner abstrahiert genau hinreichend,
und die Ebenen der Abstraktion hast du konditional in eine
Hierarchie geordnet. Wie beschreibt man diesen gegebenen
Vorgang der Unterscheidung von Abstraktionsebenen
in C-Normbegriffen?


Näher an C:
Wenn ich nicht wissen möchte, welche wahrscheinliche
Breite eine Ganzzahl in einem C-Programm haben wird,
weil z.B. mein Programm mit den Fingern einer Hand
zu tun hat, liefert mir die folgende Schreibweise genau das:

typedef short|int|long whole_number;

Hoffentlich kann in d.c.l.c diese nur andeutende Schreibweise
einer möglichen Auswahl aus "short", "int", oder "long"
verstanden werden, auch wenn die Definition von C sie
nicht oder anders abdeckt.
Post by Thomas Steinbach
Es ist schlicht
Bloedsinn, in einer ernsthaften Diskussion um die Sprache C
Das liegt der Hund begraben: Benamungs-Strategien werden in C nicht
gegeben, nur die Mittel dafür. Sie sind aber für C-Programme
wichtig, und wie hier diskutiert, in verschiedener Hinsicht...
Claus Reibenstein
2009-10-15 14:38:53 UTC
Permalink
Post by Georg Bauhaus
Post by Juergen Ilse
Hier von "auf der und jener Ab-
straktionsebene ist es das gleiche" herumzufaseln, zeugt meiner Ansicht
nach nur von einem falschen Verstaendnis der Sprache.
Von welcher falsch verstandenen Sprache sprichst du,
wenn du eine Definition von "Abstraktionsebene" Gefasel nennst?
Da wir hier in dclc sind, vermute ich mal C.

Gruß. Claus
Claus Reibenstein
2009-10-15 09:09:05 UTC
Permalink
Post by Claus Reibenstein
Ich weiß nicht, was Du unter "Abstraktionsebene" verstehst. Ich weiß
auch nicht, was Markus damit meint. Vielleicht definiert Ihr beiden
erst einmal diesen Begriff.
Abstraktion ist ein Vorgang, bei dem [...]
Sorry, aber das ist mir _zu_ abstrakt.

Gruß. Claus
Rainer Weikusat
2009-10-14 13:12:36 UTC
Permalink
Post by Thomas Koller
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, sind die Programmzeilen
#define PI 3.14159265
und
const double PI = 3.14159265;
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir hier
sprechen" im posting oben nicht gelesen.
Das vollstaendige Zitat war

,----
| Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
| wir hier sprechen, sind die Programmzeilen
| 3.14159265
| #define PI 3.14159265
|
| und
|
| const double PI = 3.14159265;
|
| noch äquivalent: Sie weisen der Zeichenkette "3.14159265" eine kürzere
| Zeichenkette als Bezeichner zu.
`----

Eine solche 'Abstraktionsebene' gibt es aber gar nicht: Beide Zeilen
sind zunaechsteinmal Zeichenfolgen (eigentlich Glyphen). Bedeutung
erhalten sie lediglich dadurch, dass sie in einem bestimmten Kontext
interpretiert werden. In diesem Fall ist der Kontext die
C-Sprachdefinition. Die erste definiert ein 'objektartiges Makro' und
veranlasst den Praeprozessor, jedes im Folgenden auftretende
Praeprozessor-Token 'PI' durch das Praeprozessor-Token '3.14159265' zu
ersetzen. Die zweite definiert ein konstantes Objekt vom Typ double,
auf das ein Bezeichner 'PI' mit statischer Speicherdauer und externer
Bindung verweist, dessen Wert 3.14159265 ist. Da werden nirgends
Zeichenketten anderen Zeichenketten 'zugewiesen' und, bezugnehmend auf
die urspruengliche Fragestellung, es werden auch keine Aliases fuer
irgendetwas existierendes definiert. Das Literal 3.14159265 ist etwas
anderes als das Praeprozessor-Token 3.14159265 und beide unterscheiden
sich von dem 'Objekt PI'. Fuer einen Definition a la

typedef int maeusekot;

gilt das nicht. Im Gueltigkeitsbereich dieser Definition sind 'int'
und 'maeusekot' Synonyme und die Frage, warum man, ausser um einen Leser
zu verwirren, solche Synonyme benutzen wollen koennte, ist nicht
ganz unberechtigt. Fuer Funktionszeiger gibt es uebrigens noch ein
besseres Beispiel: C kennt auch Funktionstypen und auch solchen
koennen typedef-Namen zugeordnet werden, als zB (im dasselbe Beispiel
zu nehmen)

typedef void sighandler(int);

Der signal-Prototyp saehe dann so aus:

sighandler *signal(int, sighandler *)

wodurch im Nachhinein vom Erfinder der Sprache als unguenstig
angesehene Effekte des 'definition resembles uses'-Prinzips umgangen
werden koennen ohne 'sone und solche' Zeigerdeklarationen im Code zu
haben.
Thomas Koller
2009-10-14 14:21:37 UTC
Permalink
Post by Rainer Weikusat
Post by Thomas Koller
Post by Juergen Ilse
Post by Markus Wichmann
Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
wir hier sprechen, sind die Programmzeilen
#define PI 3.14159265
und
const double PI = 3.14159265;
Das sind sie *nicht* (was ich mit meinem Beitrag zu verdeutlichen versuchte).
Du hast offensichtlich das "Auf der Abstraktionsebene, von der wir hier
sprechen" im posting oben nicht gelesen.
Das vollstaendige Zitat war
,----
| Man kann es auch _zu_ genau nehmen. Auf der Abstraktionsebene, von der
| wir hier sprechen, sind die Programmzeilen
| 3.14159265
| #define PI 3.14159265
|
| und
|
| const double PI = 3.14159265;
|
| noch äquivalent: Sie weisen der Zeichenkette "3.14159265" eine kürzere
| Zeichenkette als Bezeichner zu.
`----
Doch natürlich gibt es sowas. Oder bist du zur Abstraktion nicht fähig?
Würde mich aber wundern.
Post by Rainer Weikusat
Beide Zeilen
sind zunaechsteinmal Zeichenfolgen (eigentlich Glyphen). Bedeutung
erhalten sie lediglich dadurch, dass sie in einem bestimmten Kontext
interpretiert werden. In diesem Fall ist der Kontext die
C-Sprachdefinition.
Nein, er hat ja extra erwähnt dass es nicht im Kontext der
C-Sprachdefinition (was natürlich hier erstmal default ist, daher
ist deine Verwirrung am Anfang durchaus verständlich) gemeint
ist, sondern auf einer anderen Abstraktionsebene.
Post by Rainer Weikusat
Die erste definiert ein 'objektartiges Makro' und
veranlasst den Praeprozessor, jedes im Folgenden auftretende
Praeprozessor-Token 'PI' durch das Praeprozessor-Token '3.14159265' zu
ersetzen. Die zweite definiert ein konstantes Objekt vom Typ double,
auf das ein Bezeichner 'PI' mit statischer Speicherdauer und externer
Bindung verweist, dessen Wert 3.14159265 ist. Da werden nirgends
Zeichenketten anderen Zeichenketten 'zugewiesen' und, bezugnehmend auf
die urspruengliche Fragestellung, es werden auch keine Aliases fuer
irgendetwas existierendes definiert. Das Literal 3.14159265 ist etwas
anderes als das Praeprozessor-Token 3.14159265 und beide unterscheiden
sich von dem 'Objekt PI'. Fuer einen Definition a la
typedef int maeusekot;
gilt das nicht. Im Gueltigkeitsbereich dieser Definition sind 'int'
und 'maeusekot' Synonyme und die Frage, warum man, ausser um einen Leser
zu verwirren, solche Synonyme benutzen wollen koennte, ist nicht
ganz unberechtigt. Fuer Funktionszeiger gibt es uebrigens noch ein
besseres Beispiel: C kennt auch Funktionstypen und auch solchen
koennen typedef-Namen zugeordnet werden, als zB (im dasselbe Beispiel
zu nehmen)
typedef void sighandler(int);
sighandler *signal(int, sighandler *)
wodurch im Nachhinein vom Erfinder der Sprache als unguenstig
angesehene Effekte des 'definition resembles uses'-Prinzips umgangen
werden koennen ohne 'sone und solche' Zeigerdeklarationen im Code zu
haben.
Du bist mit diesen Detailanalysen deutlich eine Abstraktionsebene
tiefer als der OP. Kein Wunder dass ihr aneinander vorbei redet.

Tom
Rainer Weikusat
2009-10-15 19:20:10 UTC
Permalink
[...]
Post by Thomas Koller
Post by Rainer Weikusat
| #define PI 3.14159265
[...]
Post by Thomas Koller
Post by Rainer Weikusat
| const double PI = 3.14159265;
|
| noch äquivalent: Sie weisen der Zeichenkette "3.14159265" eine kürzere
| Zeichenkette als Bezeichner zu.
`----
[...]
Post by Thomas Koller
Post by Rainer Weikusat
Beide Zeilen
sind zunaechsteinmal Zeichenfolgen (eigentlich Glyphen). Bedeutung
erhalten sie lediglich dadurch, dass sie in einem bestimmten Kontext
interpretiert werden. In diesem Fall ist der Kontext die
C-Sprachdefinition.
Nein, er hat ja extra erwähnt dass es nicht im Kontext der
C-Sprachdefinition (was natürlich hier erstmal default ist, daher
ist deine Verwirrung am Anfang durchaus verständlich) gemeint
ist, sondern auf einer anderen Abstraktionsebene.
Worauf ich hinauswollte war, dass es sich weniger um eine 'andere
Abstraktionsebene' handelt, sondern um einen vollkommen anderen
Bezugsrahmen und obendrein um einen, der nur aufgrund oberflaechlicher
Aehnlichkeiten im konkreten Beispiel ueberhaupt sinnvoll zu sein
scheint. ZB sind

const int PI = 3.14159265;

oder

volatile const double PI = 3.14159265;

auch gueltige Definitionen konstanter Objekte, bei denen die
'Zeichenkettensubstitionserklaerung' versagt, im ersten Fall ziemlich
deutlich (automatische Umwandlung des Literals in einen Wert mit Typ
'int'), im zweiten etwas subtiler (Wert darf nicht 'inline' benutzt
werden, weil Lesezugriffe auf das Objekt als seiteneffektbehaftet
gelten sollen).
Thomas Koenig
2009-10-17 22:02:34 UTC
Permalink
Post by Rainer Weikusat
volatile const double PI = 3.14159265;
Should the value of PI change, ...
Rainer Weikusat
2009-10-19 10:04:17 UTC
Permalink
Post by Thomas Koenig
Post by Rainer Weikusat
volatile const double PI = 3.14159265;
Should the value of PI change, ...
Der Sinn dieser Bemerkung im gegebenen Zusammenhang verschliesst sich
mir.
Thomas Koller
2009-10-19 10:48:47 UTC
Permalink
Post by Rainer Weikusat
Post by Thomas Koenig
Post by Rainer Weikusat
volatile const double PI = 3.14159265;
Should the value of PI change, ...
Der Sinn dieser Bemerkung im gegebenen Zusammenhang verschliesst sich
mir.
Nicht?

Ich dachte du wüsstest das. Ich fand die Bemerkung lustig. :-)

Aber da hier vielleicht auch C-Neulinge mitlesen, ein kleines Zitat
aus dem Standard:

"An object declared
extern const volatile int real_time_clock;
may be modifiable by hardware"

Tom
Rainer Weikusat
2009-10-19 17:38:20 UTC
Permalink
Post by Thomas Koller
Post by Rainer Weikusat
Post by Thomas Koenig
Post by Rainer Weikusat
volatile const double PI = 3.14159265;
Should the value of PI change, ...
Der Sinn dieser Bemerkung im gegebenen Zusammenhang verschliesst sich
mir.
Nicht?
Ich dachte du wüsstest das. Ich fand die Bemerkung lustig. :-)
Aber da hier vielleicht auch C-Neulinge mitlesen, ein kleines Zitat
"An object declared
extern const volatile int real_time_clock;
may be modifiable by hardware"
Und welchen Sinn hat das jetzt im Zusammenhang mit einem Text, der
urspruenglich (unter anderem) 'Definitionen konstanter Objekte in C'
zum Inhalt hatte und mehr oder minder zufaellig ein konkretes Beispiel
aus einem anderen Text uebernommen hatte? Technisch gesehen ist die
Aussage, dass ich den mir zugeschriebenen Text geschrieben haette,
schlicht falsch, denn 'Veraenderungen von als konstant definiterten
Objekten' kamen in meinem Text nicht vor.
Thomas Koller
2009-10-19 17:50:01 UTC
Permalink
Post by Rainer Weikusat
Post by Thomas Koller
Post by Rainer Weikusat
Post by Thomas Koenig
Post by Rainer Weikusat
volatile const double PI = 3.14159265;
Should the value of PI change, ...
Der Sinn dieser Bemerkung im gegebenen Zusammenhang verschliesst sich
mir.
Nicht?
Ich dachte du wüsstest das. Ich fand die Bemerkung lustig. :-)
Aber da hier vielleicht auch C-Neulinge mitlesen, ein kleines Zitat
"An object declared
extern const volatile int real_time_clock;
may be modifiable by hardware"
Und welchen Sinn hat das jetzt im Zusammenhang mit einem Text, der
urspruenglich (unter anderem) 'Definitionen konstanter Objekte in C'
zum Inhalt hatte und mehr oder minder zufaellig ein konkretes Beispiel
aus einem anderen Text uebernommen hatte?
Die Bemerkung beleuchtet das "volatile" und dass in C Konstante halt
doch nicht in jedem Fall so konstant sind wie man meinen könnte auf
humorvolle Weise.
Post by Rainer Weikusat
Technisch gesehen ist die
Aussage, dass ich den mir zugeschriebenen Text geschrieben haette,
schlicht falsch, denn 'Veraenderungen von als konstant definiterten
Objekten' kamen in meinem Text nicht vor.
? Von welchem "dir zugeschriebenen Text" sprichst du?

Tom

Stefan Reuther
2009-10-13 17:14:17 UTC
Permalink
Post by Thomas Steinbach
Ich persoenlich finde es aber doch uebersichtlicher, wenn
ich genau weiss, welches Struktur hinter einem Datentyp
steht und nicht so ein "abstrahierter" Aliasnamen.... hmmm
Gerade wenn es mehrere verschachtelte Strukturen, bzw.
Datentypen sind.
Ab einer gewissen Projektgröße willst du das nicht mehr wissen (müssen).
Und vor allem: du willst es ändern können, ohne mit cut&paste durch den
Quelltext rennen zu müssen und dabei zu hoffen, nichts zu übersehen.
Post by Thomas Steinbach
Wie schaut das bei anderen Sprachen aus, Iso-C++, ObjC, etc.?
Sind das das dort auch einfach nur Aliase?
Genauso.


Stefan
Loading...