#ifndef Verständnisfrage

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

#ifndef Verständnisfrage

Beitrag von IlikeMyLife »

Hallo alle zusammen,

nachdem ich gestern wieder einige Klassen geschrieben habe, kam mir folgende Frage auf:

ich teile meine klassen in externe dateien auf ( deklaration in .hpp und definition in .cpp ).

die .hpp-Dateien beginne ich mit folgendem Grundgerüst:

Code: Alles auswählen

#ifndef __EINEKLASSE_HPP__
#define __EINEKLASSE_HPP__
#include <iostream> // <--- Da drum geht es mir.

using namespace std;

...

#endif
ich habe schon öfter ( Foren, Fachbücher, etc ) gesehen, dass die includierten dateien, wie hier Beispielsweise die iostream noch vor die #ifndef geschrieben wird. Beides Funktioniert. Was sollte nun der Grund dafür sein, die includierten dateien noch davor zu schreiben?
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: #ifndef Verständnisfrage

Beitrag von BeRsErKeR »

Prinzipiell ist der richtige Weg, die Includes innerhalb des Include-Guards (das #ifdef) zu schreiben damit diese ggf. nicht doppelt inkludiert werden. Da Standardheader allerdings auch eigene Include-Guards besitzen funktioniert auch der andere Weg. Probleme gibt es dann aber wenn du einen Header inkludierst, der keinen eigenen Include-Guard besitzt und diesen vor dem #ifdef einbindest.

Weiterhin sind Include-Guards auch nicht immer notwendig. Header, die nur Klassendeklarationen enthalten benötigen z.B. prinzipiell keine.
Ohne Input kein Output.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

dann bleibe ich bei meinem gewohnten werdegang, dass ich die includierten Dateien innerhalb der #ifndef schreibe :-)
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von dot »

Vielleicht noch ein kleiner Hinweis dazu: Namen die einen doppelten Underscore (__) enthalten und Namen die mit einem Underscore gefolgt von einem Großbuchstaben (_X) beginnen, sind reserviert. Wenn du ganz korrekt sein willst, solltest du dir also eine bessere Namenskonvention für deine Includeguards überlegen. Für den MSVC würd ich außerdem auch noch ein #pragma once drüberstreuen ;)

Und tu niemals ein using namespace in einen Header! Zumindest nicht, wenn der Header auf irgendeinem direkten oder indirekten Pfad mal von jemand anderem eingebunden werden könnte. Grund:

Code: Alles auswählen

#include <yourlibrary.h>
#include "mystring.h"

class Foo
{
private:
  string name;  // ERROR
public:
  ...
};
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

ist ja schon ein grund für die Bad-Programming Threads ;-)

mit #pragma once werde ich mich die nächsten Tage während meines Urlaubes auseinander setzen.

das einzige, was ich in diesem Rahmen noch als Frage habe, ist die Namenskonvention die du angesprochen hast.
Was währe in diesem Zuge denn passender? Der Name an sich sollte schon im Rahmen des Datei- beziehungsweise des Klassennamens sein.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von dot »

Naja, eben was ohne __ drin oder _X am Anfang. Ich verwend normal sowas wie MYHEADER_INCLUDED.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

vielen dank ;-) das gibt mir doch mal eine gute grundlage
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: #ifndef Verständnisfrage

Beitrag von BeRsErKeR »

dot hat geschrieben:Naja, eben was ohne __ drin oder _X am Anfang. Ich verwend normal sowas wie MYHEADER_INCLUDED.
Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt. Ich handhabe das in der Regel so, dass ich den Namen des Projektes, den Dateinamen und die Dateiendung einbaue um eine größtmögliche Chance der Eindeutigkeit zu gewährleisten. Denkbar wären aber sogar UUIDs oder ähnliches.

Man sollte aber auch gucken in welchem Rahmen man programmiert. Für sich zu Hause denke ich, dass die von IlikeMyLife genannten Namen durchaus ausreichend sind.

Auf der Arbeit haben wir für große Projekte einfach sowas genutzt:

Code: Alles auswählen

#ifndef filename_h
#define filename_h
...
#endif
Das finde ich allerdings schon etwas risikoreich. Dann sollte es nämlich keine zwei gleichnamigen Dateien geben.
Ohne Input kein Output.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4859
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von Schrompf »

Beserkers Lösung ist die schlichteste, damit kann man anfangen. Ich hab allerdings mal einige Stunden einen Compilerfehler gesucht, eben gerade weil die Dateinamen identisch waren. Seitdem machen wir sowas hier:

Code: Alles auswählen

#define _Verzeichnis_Datei_h_
wohlwissend, dass das Namensschema mit den Regeln für reservierte Namen kollidiert. Mir war das lieber, als die ganzen Include-Guards in der Symbolliste der Auto Completion drin zu haben. Du musst also nicht unbedingt mit einem Unterstrich anfangen, aber irgendeine Art von Präfix würde ich empfehlen, um bei Ctrl+Space nicht permanent die Include Guards mit gelistet zu bekommen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von dot »

BeRsErKeR hat geschrieben:Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt.
Rein aus Interesse: Warum genau besonders unter Windows?
BeRsErKeR hat geschrieben:Ich handhabe das in der Regel so, dass ich den Namen des Projektes, den Dateinamen und die Dateiendung einbaue um eine größtmögliche Chance der Eindeutigkeit zu gewährleisten.
Ja, das mach ich auch so, bei MYHEADER_INCLUDED dachte ich an sowas: EZG_FRAMEWORK_H_INCLUDED
BeRsErKeR hat geschrieben:Denkbar wären aber sogar UUIDs oder ähnliches.
Gar keine schlechte Idee, aber das wär dann vermutlich doch ein wenig extrem ;)
Schrompf hat geschrieben:Mir war das lieber, als die ganzen Include-Guards in der Symbolliste der Auto Completion drin zu haben.
Gutes Argument, interessant dass mir das noch nie aufgefallen ist xD
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: #ifndef Verständnisfrage

Beitrag von BeRsErKeR »

dot hat geschrieben:
BeRsErKeR hat geschrieben:Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt.
Rein aus Interesse: Warum genau besonders unter Windows?
Wenn ich von der Windows-Welt spreche rede ich hier von der WINAPI. Und in der windows.h bzw. den ganzen Headern, die diese Datei mit sich bringt gibt es sehr viele defines. Gefühlt jedenfalls Größenordnungen mehr als z.B. in den Headern, die ich auf anderen Systemen brauche. Dass diese nicht unbedingt Namen tragen, die gängigen Include-Guard-Bezeichnungen entsprechen mag vielleicht sein, aber die Chancen einer Kollision sind mMn deutlich höher, da es einfach so viele defines gibt.
Ohne Input kein Output.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

Scheinbar ist die länge des Namens groß genug um auch längere Varianten erlauben zu können. Ich nutze mittlerweile folgende Namenskonvention:

Code: Alles auswählen

#ifndef VORNAME_NACHNAME_KLASSENNAME_HPP
#define VORNAME_NACHNAME_KLASSENNAME_HPP
Ich halte es für ziemlich ausgeschlossen, dass mein voller Vor- und Nachname + der Klassenname reserviert sein soll ;-)
für mich persönlich auch sinnvoll, da man direkt nachvollziehen kann, dass ich die Klasse geschrieben habe.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von Aramis »

Mein Prefix ist INCLUDED_ (+ Projektkuerzel). Damit werden die #define's auch intuitiv in #if's nutzbar wenn man tatsaechlich mal wissen moechte ob eines inkludiert ist.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von dot »

Unter dem von Schrompf erwähnten Gesichtspunkt der IntelliSense-Pollution, ist das so rum wohl auch die bessere Lösung...
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: #ifndef Verständnisfrage

Beitrag von BeRsErKeR »

IlikeMyLife hat geschrieben:Ich halte es für ziemlich ausgeschlossen, dass mein voller Vor- und Nachname + der Klassenname reserviert sein soll ;-)
für mich persönlich auch sinnvoll, da man direkt nachvollziehen kann, dass ich die Klasse geschrieben habe.
Dann wirds aber kompliziert, wenn mehrere Entwickler (ob parallel oder nicht) an der Datei arbeiten. Ich finde man sollte nicht unbedingt Dinge verwenden, die sich ändern können. Wenn man angeben will, wer diese Datei erstellt oder bearbeitet hat sollte man eher Kommentare verwenden. Dadurch kann man dann auch genauer werden, z.B. ausdrücken, dass jemand eine bestimmte Klasse/Funktion innerhalb der Datei geschrieben hat.
Ohne Input kein Output.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

für mich zu hause werde ich weiterhin nach diesem Prinzip arbeiten.

@ Berserker:
An sich hast du recht, was das Bearbeiten und ändern der Klasse Betrifft. Für mich macht die Konvention mit dem eigenen Namen von daher Sinn, dass ich erstens, keine Vorhandenen Bezeichnungen verwende und zweitens, direkt sehe, ob eine klasse von mir persönlich stammt oder ob diese externer natur ist.

Dieses Thema werde ich noch weiter verfeinern.

Wenn ich ( wie gewollt ), später mit mehreren personen zusammen arbeite, werde ich in diesem punkt natürlich meinen namen weg lassen, da
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: #ifndef Verständnisfrage

Beitrag von BeRsErKeR »

Tu das ruhig. Im privaten Hobby-Bereich kann man vieles tun, was sonst nicht praktisch wäre. Ich wollte es nur gesagt haben, falls hier nicht ganz so erfahrene Leute reinschauen und sich ggf. deine Konvention aneignen wollen. ;)
Ohne Input kein Output.
IlikeMyLife
Establishment
Beiträge: 212
Registriert: 08.05.2011, 09:59
Benutzertext: Feel Free

Re: #ifndef Verständnisfrage

Beitrag von IlikeMyLife »

BeRsErKeR hat geschrieben:Ich wollte es nur gesagt haben, falls hier nicht ganz so erfahrene Leute reinschauen und sich ggf. deine Konvention aneignen wollen. ;)
hahaha :D

du kannst in mir auch eine nicht so erfahrene person in diesem Bereich sehen :-) deswegen ist dein rat für mich um so nützlicher :-)
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: #ifndef Verständnisfrage

Beitrag von dot »

IlikeMyLife hat geschrieben:Für mich macht die Konvention mit dem eigenen Namen von daher Sinn, dass ich erstens, keine Vorhandenen Bezeichnungen verwende [...]
Dafür gibts namespace ;)
IlikeMyLife hat geschrieben:[...] und zweitens, direkt sehe, ob eine klasse von mir persönlich stammt oder ob diese externer natur ist.
Das hat Microsoft sich auch gedacht als sie die MFC geschrieben haben (man beachte dass dies zu einer Zeit geschah da es namespace noch nicht gab).
Aber irgendwie hat alle Welt dann gedacht, dass es eine gute Idee wäre diese Namenskonvention auch zu verwenden und damit war sie dann erst wieder sinnlos ;)
Antworten