ubuntuusers.de

Problem in C - Segmentation Fault (Core Dumped)

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

stetro hat geschrieben:

Hab ich mal so gehört \^^..

Also wir lernen C in der Schule jedoch Das was ich mache ist eigendlich unabhänig davon..
Wenns da nämlich was besseres unter linux gibt würd ich das nämlich auch einmal austesten..

Eigentlich ist jede moderne Hochsprache besser als C. C unterstützt noch nicht mal OOP (und nein, Glib ist kein Ersatz 😉 ). Wieso unbedingt C?

Hello_World

Anmeldungsdatum:
13. Juni 2006

Beiträge: 3620

lilith2k3 hat geschrieben:

@Hello World

Es gibt keinen vernünftigen Grund, den Präprozessor zum definieren von Konstanten zu verwenden

Wie wäre es mit dem Argument: Übersichtlichkeit?

Makros machen überhaupt nichts übersichtlicher, im Gegenteil. Das grundlegende Problem beim Präprozessor ist, dass er komplett unabhängig von der eigentlichen C-Syntax ist. So gelten z. B. Scoping-Regeln bei Makros nicht, der Präprozessor ist eine hirnlose Suchen-und-Ersetzen-Funktion.
Dazu habe ich übrigens eine schöne Geschichte. Ich brauchte einmal ein __attribute__((noinline)) in einem Kernelmodul. Das kompiliert im Userspace wunderbar, im Kernel aber nicht. Nach längerer Suche habe ich dann festgestellt, dass "noinline" im Kernel ein Makro für __attribute__((noinline)) ist, so dass der Compiler also __attribute__((__attribute__((noinline)))) sieht, womit er natürlich nichts anfangen kann, und die Fehlermeldung war äußerst verwirrend.

Ein mindestens ebenso wichtiger Nachteil ist, dass man Präprozessormakros nicht im Debugger sehen kann. Mal ein Beispiel:

enum Farbe {ROT,GRUEN,GELB,BLAU};
enum Farbe Farbe_meines_Autos = GELB;


Wenn ich jetzt im Debugger "print Farbe_meines_Autos" eingebe, so wird er mir "GELB" anzeigen. Im Gegensatz dazu:

#define ROT = 0
#define GRUEN = 1
#define GELB = 2
#define BLAU = 3
int Farbe_meines_Autos = GELB;


Wenn ich mir jetzt im Debugger die Farbe_meines_Autos ausgeben lasse, wird er mir 2 sagen, und ich muss erst nachsehen, was das für eine Farbe ist, und das ist extrem nervig, da Konstanten eben sehr häufig auftauchen.

Inhaltlich hast du recht!
Aber ich finde es dann lesbarer :]

Lesbar ist, was idiomatisch ist, und sizeof(char) ist das IMO nicht.

na dann lieber ne const-Variable

Warum, es handelt sich doch nur um eine Symbolische Konstante?

Darf ich fragen, was der Unterschied zwischen einer "symbolischen" Konstante und anderen Konstanten sein soll? Für Konstanten gibt es in C das const-Schlüsselwort, Makros haben da einfach keinen Platz.

Was schlägst du Hello World denn als andere Sprache vor, mit der man ('relativ') Speichergering Programmieren kann?

C++ hat zwar viele Schwächen von C übernommen, aber für die meisten zweifelhaften Konstrukte gibt es bessere Alternativen. Aber auch in Object Pascal oder Ada kann man klein und schnell programmieren.

lilith2k3

Avatar von lilith2k3

Anmeldungsdatum:
14. Dezember 2006

Beiträge: 2999

Wohnort: OS

Darf ich fragen, was der Unterschied zwischen einer "symbolischen" Konstante und anderen Konstanten sein soll? Für Konstanten gibt es in C das const-Schlüsselwort, Makros haben da einfach keinen Platz.

It's bad practice to bury "magic numbers'' like 300 and 20 in a program; they convey little information to someone who might have to read the program later, and they are hard to change in a systematic way. One way to deal with magic numbers is to give them meaningful names. A #define line defines a symbolic name or symbolic constant to be a particular string of characters:

#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */


Kerningham & Ritchie: The C Programming Language. 2nd Edition p17.

Sinn und Zweck der Geschichte ist lediglich Lesbarkeit.

Hingegen const signalisiert, daß die Variable nicht veränderbar ist während der Laufzeit (weshalb es ja auch unter den Variablendeklarationen zu finden ist)

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

lilith2k3 hat geschrieben:

Darf ich fragen, was der Unterschied zwischen einer "symbolischen" Konstante und anderen Konstanten sein soll? Für Konstanten gibt es in C das const-Schlüsselwort, Makros haben da einfach keinen Platz.

It's bad practice to bury "magic numbers'' like 300 and 20 in a program; they convey little information to someone who might have to read the program later, and they are hard to change in a systematic way. One way to deal with magic numbers is to give them meaningful names. A #define line defines a symbolic name or symbolic constant to be a particular string of characters:

#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */


Kerningham & Ritchie: The C Programming Language. 2nd Edition p17.

Sinn und Zweck der Geschichte ist lediglich Lesbarkeit.

Und was genau ist an ``#define UPPER 300`` nun lesbarer als an ``const int UPPER = 300;``? Allein die fehlenden Typsicherheit sollte eigentlich ausreichen, um von der Verwendung von Makros soweit als möglich Abstand zu nehmen. Sogar PHP und Visual Basic bieten noch mehr Typsicherheit als C-Präprozessor-Makros!

K&R ist zwar eine tolle C-Referenz, aber nicht alles, was darin empfohlen wird, darf heute noch als zeitgemäß gelten.

Bauer

Anmeldungsdatum:
28. Juni 2006

Beiträge: 333

Da #defines während der Laufzeit auch nicht änderbar sind - sind ja nur Textersetzungen - haben wir folgende Situation:

* Keine Magic Numbers mehr, Änderung an einzelner Stelle
* Konstant
* kann zu schlecht auffindbare Fehler führen (siehe Hello Worlds Geschichte)
* Debugger kriegt die nicht zu Gesicht

const:
* keine Magic Numbers mehr, Änderung an einzelner Stelle
* Konstant
* Keine falschen Ersetzungen
* Typprüfung
* Wird im Debugger vernünftig angezeigt ..

Da dürfte die Wahl ja wohl klar sein.

lilith2k3

Avatar von lilith2k3

Anmeldungsdatum:
14. Dezember 2006

Beiträge: 2999

Wohnort: OS

Und was genau ist an ``#define UPPER 300`` nun lesbarer als an ``const int UPPER = 300;``?

Ich würde mal blind tippen, daß eine Präprozessoranweisung zur Compilierzeit eine Rolle spielt, während eine mit const definierte Konstante während der Laufzeit eine Rolle spielt. Und entsprechend würde ich es auch lesen.

Edit: Aber so langsam wird's Offtopic 😀

stetro

(Themenstarter)
Avatar von stetro

Anmeldungsdatum:
14. Oktober 2006

Beiträge: 25

Jo deshalb werd ich das jetzt auch mal als gelöst makieren.

Danke nochmals..

Hello_World

Anmeldungsdatum:
13. Juni 2006

Beiträge: 3620

lilith2k3 hat geschrieben:

Ich würde mal blind tippen, daß eine Präprozessoranweisung zur Compilierzeit eine Rolle spielt, während eine mit const definierte Konstante während der Laufzeit eine Rolle spielt. Und entsprechend würde ich es auch lesen.

Ein heutiger Compiler generiert den gleichen Code, egal ob man ein Makro oder eine const-Variable verwendet (vorausgesetzt, der Code ist semantisch äquivalent).
Das Zitat aus dem K&R-Buch kommt übrigens ziemlich sicher daher, dass das const-Schlüsselwort in K&R-C nicht existierte, sondern erst mit ISO-C89 eingeführt wurde.

Darkcloud

Anmeldungsdatum:
10. Juni 2007

Beiträge: 69

Hihi, wir merken uns:
Keine #defines reinwerfen, falls Hello World in der Nähe ist (oder danach schnell abhauen)...

Wobei ich ihm da ja schon recht geben muss (hach, man wird alte Angewohnheiten teilweise leider schwer los).

lilith2k3

Avatar von lilith2k3

Anmeldungsdatum:
14. Dezember 2006

Beiträge: 2999

Wohnort: OS

Ich will ja hier keinen Streit vom Zaun brechen 😉
In dem Fall, ist es für mich eher eine Geschmacksfrage.
Hat halt jeder seine persönlichen Vorlieben.

Ein heutiger Compiler generiert den gleichen Code, egal ob man ein Makro oder eine const-Variable verwendet (vorausgesetzt, der Code ist semantisch äquivalent).

Dagegen hab ich ja auch nix \^^

Das Zitat aus dem K&R-Buch kommt übrigens ziemlich sicher daher, dass das const-Schlüsselwort in K&R-C nicht existierte, sondern erst mit ISO-C89 eingeführt wurde.

K&R hat geschrieben:

The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed.

Kerningham & Ritchie: The C Programming Language. 2nd Edition. p.39

Friede? 😉

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17620

Wohnort: Berlin

Was schlägst du Hello World denn als andere Sprache vor, mit der man ('relativ') Speichergering Programmieren kann?


Und welcher Speicher soll geschont werden?
Der Festspeicher, der RAM?
Der Speicher des Entwicklers oder der Speicher des Anwenders?
Zur Kompilezeit oder zur Laufzeit? ☺

Javaprogramme sind immer hübsch klein (solange man sie nicht startet ☺ ).

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17620

Wohnort: Berlin

lilith2k3 hat geschrieben:

Ich will ja hier keinen Streit vom Zaun brechen 😉
In dem Fall, ist es für mich eher eine Geschmacksfrage.
Hat halt jeder seine persönlichen Vorlieben.

Ich bin da ganz bei Hello World - #define-Makros sind fehleranfällig und Debuggerfeindlich.
Demnach wäre es keine Geschmacksfrage.
lilith2k3 hat geschrieben:

Ein heutiger Compiler generiert den gleichen Code, egal ob man ein Makro oder eine const-Variable verwendet (vorausgesetzt, der Code ist semantisch äquivalent).

Das würde dem debug-Argument widersprechen.
Kann das jemand mal nachprüfen?

cat a.c b.c
#define a 30
const int a=30;

gcc -c a.c
gcc -c b.c

 l [ab].[co]
-rw-r--r-- 1 stefan stefan  13 2008-05-13 22:18 a.c
-rw-r--r-- 1 stefan stefan 641 2008-05-13 22:19 a.o
-rw-r--r-- 1 stefan stefan  16 2008-05-13 22:19 b.c
-rw-r--r-- 1 stefan stefan 727 2008-05-13 22:19 b.o


Also Pi mal Daumen führt nicht beides zu gleichem Objektcode, zumindest nicht ohne weiteres.

Bauer

Anmeldungsdatum:
28. Juni 2006

Beiträge: 333

probier mal

#define a 30
int b = a + 1;

und

const int a = 30;
int b = a + 1;

Im ersten Fall hast du ja eine leere Datei kompiliert.

Apollon

Avatar von Apollon

Anmeldungsdatum:
27. Oktober 2004

Beiträge: 724

Wohnort: Darmstadt

Hello World hat geschrieben:

Lern doch lieber eine vernünftige Sprache und nicht so einen veralteten Mist wie C...

lol

Harleen

Anmeldungsdatum:
12. Februar 2006

Beiträge: 183

Wohnort: Bremen

a muss außerdem static deklariert werden, da die Variable ansonsten exportiert wird, was beim define nicht der Fall ist.
Aber solange die Optimierung nicht eingeschaltet ist, wird der Compiler natürlich keine Variablen wegoptimieren.

$ cat a.c b.c
#define a 30
static const int a=30;
$ gcc -c a.c b.c -O2
$ ls -lisa *.o
4637306 4 -rw-r--r-- 1 marko marko 641 2008-05-13 22:38 a.o
4637307 4 -rw-r--r-- 1 marko marko 641 2008-05-13 22:38 b.o

Damit kommen wir der Sache doch schon näher. Aber...

$ diff a.o b.o
Binärdateien a.o and b.o sind verschieden.

Grundsätzlich stimme ich Hello World aber zu. Bei meinem Brötchengeber stehen #defines auf der gleichen Liste wie goto. Etwas gewagt erscheint mir aber diese Aussage:
Hello World hat geschrieben:

Aber auch in [...] Ada kann man klein und schnell programmieren.

Kann man nämlich nicht. 😈