Bei einem Placement new oder std::construct_at sollte doch der Compiler
einfach die Adresse zuweisen und keine statische Initialisierung machen.
Wenn ich den nachfolgenden Code im Compiler Explorer
https://gcc.godbolt.org/ eingebe zeigt mir der GCC 12.2.noeabi bei
beiden Varianten statischen Initialisierungscode an. Warum ?
Optionen : -std=c++20 -Og
Hans-Georg L. schrieb:> Warum ?
Weil deine Variablen nicht constinit/constexpr sind und daher eben
Laufzeit-initialisiert werden. Eigentlich müsstest du "constinit"
hinzufügen, aber reinterpret_cast ist in constant expressions nicht
erlaubt.
placement-new bzw construct_at ist eigentlich eh das falsche Werkzeug,
du willst ja keinen Konstruktor auf den Peripherie-Registern aufrufen!
Man muss den Cast auf die Laufzeit verschieben, und im constant
expression Kontext halt nur mit dem Integer hantieren. z.B. so:
https://gcc.godbolt.org/z/cejd945na
Die Variablen gpio_A und gpio_B sind leere Dummys und belegen keinen
Speicher, erst beim Aufruf des Pfeil-Operators erfolgt der Cast. Also
eben zur Laufzeit, nur durch das Inlinen wird es dann effizient.
Aber ob das jetzt so schön ist...
Niklas G. schrieb:> Aber ob das jetzt so schön ist...
Also ich würd's kaufen. Insbesondere die Trennung der Registerstruktur
und der Klasse für den Speicherzugriff ist doch sehr schön. So ginge
auch:
https://gcc.godbolt.org/z/E94PfaPrK
Sieht auf den ersten Blick ein klitzeklein wenig einfacher aus weil auf
die Trennung verzichtet wird, ebenso auf die statische Variable. Es wird
trotzdem gleiche Maschinencode erzeugt. Mit -Os oder -Oz wird's sogar
noch kleiner.
Richard W. schrieb:> Sieht auf den ersten Blick ein klitzeklein wenig einfacher aus
Gefällt mir nicht so ganz weil es so keinen nicht-templatisierten
"gpio_type" gibt. Dadurch kann man kein "gpio_type*" als
Funktionsparameter übergeben o.ä.
Hallo,
mein Grundgerüst aus 2021 sieht wie folgt aus. Ist erstmal viel
Tipparbeit aus dem Manual um die Registerstruktur aufzubauen. Ab da geht
es leichter.
1
AVRxDB32_PinRegister.h
2
3
#pragma once
4
5
namespacePins
6
{
7
namespaceAddr
8
{
9
structOffset// Offsets der Registeradressen
10
{
11
// VPORTs
12
constuint8_tvDir=0x00;
13
constuint8_tvOut=0x01;
14
constuint8_tvIn=0x02;
15
constuint8_tvFlag=0x03;
16
// PORTs
17
constuint8_tdir=0x00;
18
constuint8_tdirSet=0x01;
19
constuint8_tdirClear=0x02;
20
constuint8_tdirToggle=0x03;
21
constuint8_tout=0x04;
22
usw.
23
};
24
constexprOffsetaddrOffset;
25
26
structAddress// base addresses of registers
27
{
28
uint16_tvport;
29
uint16_tport;
30
uint8_tpinCtrl;
31
uint8_tmask;
32
};
33
34
constexprAddressbaseAddr[]
35
{
36
// | VPORT | PORT | PINn | BIT | // | Arduino | Package |
37
// | Base | Base | CTRL | MASK | // BIT | Pin | Pin | PORT
Hallo,
dann muss ich aber jetzt einmal blöd fragen, warum meckert dann der
Compiler nicht? Also man kann sich ja nicht über etwas aufregen, was
angeblich falsch sein soll, was jedoch funktioniert. Ich verstehe das
Problem das mein Code nicht auf Linux kompilierbar ist, dass habe ich
verstanden. Nur dann muss der Compiler meckern und die Vorgabe machen,
wenn es überall gleichgezogen kompilieren sollen.
Veit D. schrieb:> warum meckert dann der Compiler nicht?
Kann ich dir nicht sagen. Weil \P und \A keine Control-Codes sind und
auf P bzw. A abgebildet werden? Frag die Compilerbauer.
> Also man kann sich ja nicht über etwas aufregen, was angeblich> falsch sein soll, was jedoch funktioniert.
Die Logik ist:
Code is korrekt => Code funktioniert
und
Code funktioniert nicht => Code ist nicht korrekt
"Code is inkorrekt" ist also nicht hinreichend dafür, dass er nicht
funktioniert. Die falsche Folgerung
Code funktioniert => Code ist korrekt
ist wohl der mit Abstand am weitesten verbreitete Denkfehler im
Softwarebereich. So auch hier. Aber spätestens wenn du ein (anderes)
Problem hast und jemandem den Code gibts, um das Problem
nachzuvollziehen, kann der Fehler akut werden. Zum Beipiel wenn dein
Kollege unter Linux, HPUX, SunOS, ... arbeitet.
Hallo,
Was ist \P und \A ?
Ich ahne worauf die Diskussion hinauslaufen wird.
Ich kürze das ab.
So richtig bewusst provokant aus der Hüfte geschossen. :-)
Warum ist Linux unfähig den Backslash im Pfad zu verstehen?
Ich befürchte, es könnte eine lange Unterhaltung werden. ;-)
Johann L. schrieb:> Veit D. schrieb:>> warum meckert dann der Compiler nicht?>> Kann ich dir nicht sagen. Weil \P und \A keine Control-Codes sind und> auf P bzw. A abgebildet werden? Frag die Compilerbauer.
Das spielt für #include-Direktiven keine Rolle.
> Die falsche Folgerung>> Code funktioniert => Code ist korrekt>> ist wohl der mit Abstand am weitesten verbreitete Denkfehler im> Softwarebereich.
Wohl war.
Veit D. schrieb:> Was ist \P und \A ?
Nichts, das war ja der Punkt. Es gibt in C gewisse mit \ eingeleitete
Sequenzen wie \n für ein Newline. \P und \A gibt es aber nicht.
Bei #include gibt's davon aber extra eine Ausnahme. Man kann also z.B.
schreiben:
1
#include"a\b.txt"
um eine Datei namens a\b.txt einzubinden, aber nicht:
1
fopen("a\b.txt","rt");
um eine solche Datei zu öffnen, da \b das Backspace-Zeichen ist. Damit
wird die Datei dann also nicht gefunden. Und wenn man es mit a\c.txt
versucht, gibt's gar einen Fehler vom Compiler, da es keine
Escape-Sequenz \c gibt.
> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?
Verstehen tut es den durchaus, aber eben als Escape-Zeichen und nicht
als Verzeichnis-Trenner. So war das in C und unter unixoiden Systemen
schon lange, bevor Windows, oder auch DOS, überhaupt existiert hat.
Veit D. schrieb:> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?
Linux ist sehr wohl fähig Backslashes im Pfad nicht nur zu erkennen.
sondern sie zudem korrekt zu benutzen.
1
ls "Peter Pan"
1
ls Peter\ Pan
funktioniert zB. beides. Und ja, man kann selbstverständlich auch ASCII
Ctrl-Chars unterbringen, sollte man dieses seltsame Bedürfnis verspüren.
Es liegt an Windows, dass man ihm jeden Stuss vorsetzen kann.
Slash, Backslash, Groß, Klein, Windows frisst eine Menge Zeug und es
macht eine Menge irrer Annahmen um das Geraffel irgendwie zum Laufen zu
bringen.
Altlasten aus der Zeit der Altvorderen.
Das schöne bei Linux ./. was-anderes-Flamewars ist die extreme Einsicht,
die die beiden Seiten jeweils aufbringen, indem sie ihre Seite der Dinge
als die einzig mögliche und einzig richtige darstellen.
So funktionieren Religionen.
Harald K. schrieb:> Das schöne bei Linux ./. was-anderes-Flamewars ist die extreme> Einsicht,> die die beiden Seiten jeweils aufbringen, indem sie ihre Seite der Dinge> als die einzig mögliche und einzig richtige darstellen.
Macht keiner. ›Einzig möglich‹ ist ja durch Windows schon widerlegt.
›Einzig richtig‹ wohl auch nicht, das ist durch andere Systeme
widerlegt.
Wenn man aber der Ansicht ist, dass es egal ist ob man ›\‹ oder ›/‹ oder
gar beides bunt gemischt benutzt, dann stimme ich dir zu.
Wenn man "ABC, "abc","AbC",… als gleich ansieht, dann stimme ich dir zu.
PS. Ist der Explorer mittlerweile in der Lage mit einer einzelnen
Operation die Groß/Kleinschreibung (umbenennen) einer Datei
durchzuführen, oder braucht es dazu immer noch zwei Operationen?
Edit:
Norbert schrieb:> Altlasten aus der Zeit der Altvorderen.
Damit meine ich übrigens, dass in den Anfängen zunächst erst 8.3(immer
Groß) zulässig war. Dann ging's etwas länger (zumindest stark begrenzt
länger), dann kam Groß/Klein dazu, dann ging's noch länger, dann gab's
eine Zeit während der die Dateinamen/Pfadnamen Begrenzungen nicht sauber
in den SDKs definiert waren, usw.
Irgendwann zeitlich dazwischen — das wird sicherlich jemand besser
wissen als ich — konnte man plötzlich ›\‹ UND ›/‹ verwenden.
Der / als Pfad-Trenner ist eine Degign-Entscheidung von C/C++. Hätte
man natürlich auch was anderes nehmen können wie @.
Jedenfalls war die Entscheidung, die Quellen unabhängig vom Host-System
zu halten, eine gute.
Johann L. schrieb:> Der / als Pfad-Trenner ist eine Degign-Entscheidung von C/C++.> Hätte> man natürlich auch was anderes nehmen können wie @.>> Jedenfalls war die Entscheidung, die Quellen unabhängig vom Host-System> zu halten, eine gute.
Na ja, aber Veit hat hier
Beitrag "Re: GCC Statische initialisierung." schon die richtige
Frage gestellt.
Womöglich wird der ganze (Pfad-)String (ob nun richtig oder falsch)
einfach an das Betriebssystem zur Öffnung übergeben und auf etwaige
Fehler überprüft. Und da liefert Windows halt ein OK. Das wäre jetzt
zumindest meine Vermutung. Ergo prüft ›C‹** evtl. nicht wirklich was da
im (Pfad-)String drin steht.
** Wohl eher der Präprozessor
Johann L. schrieb:> Veit D. schrieb:>> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?>> Warum ist Windows unfähig den Slash im Pfad zu verstehen?
Ist es ja gar nicht. Schon MS-DOS 3.x konnte den Slash intern als
Pfad-Trenner benutzen. Lediglich command.com und dessen Nachfolger
haben den Slash als Options-Zeichen benutzt (statt Bindestrich in Unix)
und brauch(t)en daher den Backslash.
Intern (auf Ebene der Systemaufrufe) funktioniert der Vorwärtsstrich,
weshalb man im Sinne der Portabilität gut daran tut, diesen auch bei
Windows durchweg innerhalb von Programmen zu verwenden. Ganz nebenbei
umgeht man dadurch potenzielle Probleme der Fehlinterpretation von durch
Backslash eingeleiteten Escape-Sequenzen – nicht nur bei C, auch andere
Sprachen haben dieses Konzept ja.
Veit D. schrieb:> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?
Der Slash als Trenner in Pfaden existiert bereits seit 1970 (UNIX), da
gab es noch keine Betriebssysteme von Microsoft. Warum MS sich dann für
den Backslash entschied, könnte an Jörgs Erklärung liegen: MS hat den
Slash für Kommando-Optionen genutzt - vermutlich, bevor überhaupt
Unterverzeichnisse in MS-DOS eingeführt wurden. Das war damals schon
eine krasse Fehlentscheidung.
Warum unterstützt der GCC Backslashes in Include-Pfaden unter Windows?
Wahrscheinlich aus Mitleid - um es vorsichtig auszudrücken.
P.S.
Browser wie Edge, Chrome und Firefox unterstützen auch URLs mit
Backslashes wie zum Beispiel:
1
https:\\www.mikrocontroller.net\topic\580316
Obwohl Backslashes meines Wissens nach in URLs gar nicht so
funktionieren dürfen - siehe RFC 3986.
Johann L. schrieb:> Der / als Pfad-Trenner ist eine Degign-Entscheidung von C/C++.
Nö. C interessiert sich überhaupt nicht für Pfadtrenner. Bei #include
sagt es einfach, dass es systemspezifisch ist, wie der dort angegebene
Name in einen Dateinamen übersetzt wird oder ob da überhaupt echte
Dateien dahinter stehen.
> Jedenfalls war die Entscheidung, die Quellen unabhängig vom Host-System> zu halten, eine gute.
Das ist aber keine Entscheidung von C oder C++.
Jörg W. schrieb:> Johann L. schrieb:>> Veit D. schrieb:>>> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?>>>> Warum ist Windows unfähig den Slash im Pfad zu verstehen?>> Ist es ja gar nicht. Schon MS-DOS 3.x konnte den Slash intern als> Pfad-Trenner benutzen. Lediglich command.com und dessen Nachfolger> haben den Slash als Options-Zeichen benutzt (statt Bindestrich in Unix)> und brauch(t)en daher den Backslash.
Nicht nur das, sondern sie haben auch erlaubt, das trennende Leerzeichen
zwischen Programmname und Parameter weglassen zu können, wie z.B.:
1
dir/p
Wäre ein trennendes Leerzeichen erforderlich, dann wäre es auch kein
Problem gewesen, den / als Verzeichnistrenner in command.com zu
unterstützen.
> Warum unterstützt der GCC Backslashes in Include-Pfaden unter Windows?> Wahrscheinlich aus Mitleid - um es vorsichtig auszudrücken.
Ich vermute eher, weil die anderen Compiler für Windows es auch können
und weil man, um es nicht zu können, extra zusätzlichen Code einbauen
müsste. Tut man nichts dagegen, dann funktioniert es automatisch.
Frank M. schrieb:> Warum unterstützt der GCC Backslashes in Include-Pfaden unter Windows?> Wahrscheinlich aus Mitleid - um es vorsichtig auszudrücken.
Naja es macht schon Sinn das native Pfad-Format des jeweiligen Host-OS
zu verstehen. Diskutabel ist, ob bei Ausgaben auch (standardmäßig) das
native Format verwendet werden sollte, beim Compiler also z.B. in den
Pfaden der Debug-Informationen.
CMake unterstützt z.B. bei manchen Eingabe-Pfaden auch unter Windows
ausschließlich Unix-Trennzeichen, während z.B. VS Code den Pfad zum
aktuellen Projekt in der Kommandozeilen-Substitution mit Backslashes
generiert, sodass man das nicht direkt an CMake übergeben kann - sehr
ungünstig!
Außerdem sieht "C:/Users/ich/..." schon irgendwie komisch aus 😉
Frank M. schrieb:> Warum unterstützt der GCC Backslashes in Include-Pfaden unter Windows?
Ich denke, die Erklärung ist viel einfacher, als die meisten vermuten:
weil ihn das gar nicht interessiert. Alles zwischen den Spitzklammern
oder Anführungszeichen nach #include wird am Ende an das OS
weitergereicht. Deshalb funktionieren die Vorwärtsstriche eben auch
unter Windows (und sowas wie #include <sys/stat.h> gab es meiner
Erinnerung nach schon in den ersten Versionen von Turbo-C), denn die
Syscalls dort kommen ja damit klar.
ISO 9899-1999 6.4.7:
If the characters ', \, ", //, or /* occur in the sequence between the <
and > delimiters, the behavior is undefined. Similarly, if the
characters ', \, //, or /* occur in the sequence between the "
delimiters, the behavior is undefined.
Niklas G. schrieb:> Außerdem sieht "C:/Users/ich/..." schon irgendwie komisch aus
Noch seltsamer sieht es ja als URL aus, z.B. im Browser:
file:///C/Users/ich/...
Zino schrieb:> ISO 9899-1999 6.4.7:>> If the characters ', \, ", //, or /* occur in the sequence between the <> and > delimiters, the behavior is undefined. Similarly, if the> characters ', \, //, or /* occur in the sequence between the "> delimiters, the behavior is undefined.
Hmm, interessant. Das heißt, dass man bei #include den \ als
Verzeichnistrenner in C eigentlich gar nicht verwenden darf.
Die praktisch gleiche Regel gibt es in C++ übrigens auch.
Und da es hier ja eigentlich um C++ geht noch 2.8 aus ISO 14882:
If either of the characters ’ or \, or either of the character sequences
/* or // appears in a q-char-sequence or a h-char-sequence, or the
character " appears in a h-char-sequence, the behavior is undefined
Wohlgemerkt: "undefined", nicht "implementation-defined"!
D.h.
1
#include<sys\stat.h>
ist in C++ (anders als in C99) erlaubt, wohingegen die Bedeutung von
Und in C++23 ist es wieder anders (das Zitat oben war für C++03):
The appearance of either of the characters ’ or \ or of either of the
character sequences /* or // in a q-char-sequence or an h-char-sequence
is conditionally-supported with implementation-defined semantics, as is
the appearance of the character " in an h-char-sequence.[13]
13) Thus, a sequence of characters that resembles an escape sequence can
result in an error, be interpreted as the character corresponding to the
escape sequence, or have a completely different meaning, depending on
the implementation.
Zino schrieb:> Allerdings ist> #include <sys\stat.h>> in C++ zwar erlaubt, aber nicht portabel.
Portabel ist in dem Sinne aber sowieso nichts, außer den
Standard-Header-Namen, und die enthalten soweit ich weiß keine
Verzeichnistrenner.
Zino schrieb:> Z.B. der Header sys/stat.h wird von IEEE 1003 definiert. Mit /.
Mit Standard-Header meinte ich jetzt explizit die aus dem C- und dem
C++-Standard. Bei POSIX sieht's natürlich wieder anders aus. Windows ist
aber nicht POSIX-konform.
Johann L. schrieb:> Veit D. schrieb:>> Warum ist Linux unfähig den Backslash im Pfad zu verstehen?>> Warum ist Windows unfähig den Slash im Pfad zu verstehen?
Sorry, aber genau diese Frage stellt sich unter Windows nicht. Es kann
mit Slash und Backslash umgehen. Kann man auch in der DOS-Box bzw. im
cmd prompt ausprobieren. Ansonsten hätte ich den include Pfad wie
gezeigt überhaupt nicht schreiben können und ich hätte nicht diese
provokante Frage gestellt.
Hallo,
zur Beruhigung der Massen.
Da ich nur unter Windows programmiere fiel mir das eben noch nicht auf
bzw. dachte es wäre egal. Bewusst um jemanden zu ärgern habe ich das
jedenfalls nicht gemacht. Ich werde in Zukunft / verwenden als
Pfadtrenner. Glücklicherweise kann Windows damit umgehen. ;-) Was man
nicht alles als Windows User macht damit Linuxer glücklich sind. ;-)
Veit D. schrieb:> Was man nicht alles als Windows User macht damit Linuxer glücklich sind. ;-)
Backslashes bei #include waren schon undefined behavior bevor es
Linux(er) gab.
Zino schrieb:> Veit D. schrieb:>> Was man nicht alles als Windows User macht damit Linuxer glücklich sind. ;-)>> Backslashes bei #include waren schon undefined behavior bevor es> Linux(er) gab.
Irgendwas stimmt an der Aussage nicht.
a) unter Windows sind Backslash Standard
b) wird der Pfad von include vom Dateisystem vom OS aufgelöst
Ansonsten würde es mit Backslash unter Windows und include nicht
funktionieren. Man kann nicht etwas unverständliches dem Compiler
übergeben, der wiederum auf das Dateisystem mit falscher Pfadangabe
zugreift. Irgendwann wäre mir ein "undefined behavior" aufgefallen in
den Jahren. Weil ansonsten hätte es direkt beim Kompilieren eine
Fehlermeldung gegeben mit Pfad nicht gefunden o.ä.. Irgendwelche
versteckten Fehler zur Laufzeit kann es dabei nicht geben.
Der zitierte Spruch war auch anders gemeint. Windows User haben mit
Backslash und include keine Problem zu erwarten. Im include gibt es
keine Escape-Zeichen. Das Problem mit Backslash beginnt, wie von Johann
richtig erkannt, wenn man es mit Backslash unter Linux verwenden möchte.
Dann muss man alle Pfadangaben korrigieren. Das heißt ich als Windows
User korrigiere die Pfadangaben erstmal primär für potentielle Linuxer.
Weil sich das bei mir nicht auswirkt. Das war der Witz im Spruch. ;-)
Bei mir korrigiert das OS Dateisystem den Slash zurück in Backslash für
die Pfadangabe und Dateizugriff. Weil unter Linux ist Slash Standard und
unter Windows ist Backslash Standard. Irgendein OS User muss die Hürde
nehmen.
Weil aber ein Escape-Zeichen den Backslash benötigt, verwendet man beim
Programmieren besser Slash als Pfadtrenner. Das heißt der Windows User
muss die Gedanken zusammennehmen.
Veit D. schrieb:> Irgendwas stimmt an der Aussage nicht.> a) unter Windows sind Backslash Standard> b) wird der Pfad von include vom Dateisystem vom OS aufgelöst
In den C- und C++-Standards ist das, was man hinter #include in spitzen
Klammern oder Anführungszeichen angibt, gar nicht als Pfadname
spezifiziert. Also sind Deine beiden Beobachtungen für ISO 9899 (C) und
ISO 14882 (C++) nicht relevant.
Vielmehr ist das "Argument" von #include irgendetwas, das auf
implementationsspezifische Weise auf einen Header oder eine Quelldatei
abgebildet wird. Z.B. braucht keine Datei namens stdio.h zu existieren
solange
Veit D. schrieb:> Das Problem mit Backslash beginnt, wie von Johann> richtig erkannt, wenn man es mit Backslash unter Linux verwenden möchte.
Warum sollte man das wollen? Als C erfunden wurde, hat keiner
Backslashes zur Trennung von Komponenten in Pfadnamen verwendet.
Veit D. schrieb:> Das heißt ich als Windows User korrigiere die> Pfadangaben erstmal primär für potentielle Linuxer.
Du machst es in erster Linie für dich selbst (falls du den Code für dich
selbst schreibst).
Oder wenn du in nem Forum was zum Code fragst oder nen Bugreport machst.
Jedenfalls scheint das Thema dich ziemlich aufzureiben...
Die Programmiersprachen C und C++ (ohne Beachtung der
Standardbibliotheken) kennen das Konzept "Pfadnamen" gar nicht. Es gibt
auch keine Unterverzeichnisse oder ähnliches, keine Komponenten von
Pfadnamen, keine Trennzeichen. Wie Dein Lieblingsbetrübssystem Pfadnamen
definiert, ist also völlig irrelevant. Es gelten die Regeln, die ISO
9899 bzw. ISO 14882 für #include festlegen.
1
#include"include\Pin\AVRxDB32_PinRegister.h"
ist erst seit (ungefähr, mein Archiv ist lückenhaft) C++23 nicht mehr
völlig undefiniert.
Veit D. schrieb:> b) wird der Pfad von include vom Dateisystem vom OS aufgelöst
Damit ist trotzdem nicht völlig eindeutig, ob
1
#include"subdir\neuedatei.h"
nun als "neuedatei.h" in "subdir" interpretiert wird oder als
"subdir^Jeuedatei.h", denn der Backslash leitet in einem String eine
Escape-Sequenz ein.
Deshalb ist es eben, je nach Standard, entweder undefined behaviour oder
implementation defined.
Aber "..." bei #include "..." ist gar kein string-literal sondern ein
Anführungszeichen gefolgt von einer q-char-sequence gefolgt von einem
Anführungszeichen. Interessanter wird es bei
1
#define N "subdir\neuedatei.h"
2
#include N
Da gilt zunächst die Syntax von pp-token (also hier string-literal) und
dann die von q-char-sequence.
Veit D. schrieb:>> Backslashes bei #include waren schon undefined behavior bevor es>> Linux(er) gab.>> Irgendwas stimmt an der Aussage nicht.> a) unter Windows sind Backslash Standard
Das ist für C nicht relevant. Wie schon ein paar mal erwähnt, gab es
Windows noch gar nicht, als das für C definiert wurde, und kein Mensch
hat \ als Verzeichnistrenner verwendet.
> b) wird der Pfad von include vom Dateisystem vom OS aufgelöst
Nein, er wird auf impelmetationsspezifische Weise vom Compiler in
Dateinamen oder ggf. auch was anderes transformiert, um damit auf den
Header zuzugreifen. Diese Transformation kann natürlich auch daraus
bestehen, dass der Compiler den Namen 1:1 an die Betriebssystem-Funktion
weitergibt, aber das ist dann Sache des Compilers, nicht des Standards.
> Ansonsten würde es mit Backslash unter Windows und include nicht> funktionieren. Man kann nicht etwas unverständliches dem Compiler> übergeben, der wiederum auf das Dateisystem mit falscher Pfadangabe> zugreift. Irgendwann wäre mir ein "undefined behavior" aufgefallen in> den Jahren.
Undefined behavior heißt nicht, dass der Standard verlangt, dass es
nicht funktioniert, sondern nur, dass aus Sicht des Standards beliebiges
passieren kann, wenn du es versuchst. Ab dem Zeitpunkt, zu dem du
undefiniertes Verhalten hervorrufst, darf der Compiler machen, was immer
er will, und das nicht nur mit dem spezifischen Konstrukt, der es
hervorgerufen hat, sondern mit dem gesamten Programm. Wie gesagt heißt
das nicht, dass etwas komisches passieren muss, aber es darf, und
der Compiler ist dann immer noch standardkonform.
> Weil ansonsten hätte es direkt beim Kompilieren eine> Fehlermeldung gegeben mit Pfad nicht gefunden o.ä.. Irgendwelche> versteckten Fehler zur Laufzeit kann es dabei nicht geben.
Auch das entspricht nicht dem, was Undefined Behavior bedeutet.
> Der zitierte Spruch war auch anders gemeint. Windows User haben mit> Backslash und include keine Problem zu erwarten. Im include gibt es> keine Escape-Zeichen. Das Problem mit Backslash beginnt, wie von Johann> richtig erkannt, wenn man es mit Backslash unter Linux verwenden möchte.> Dann muss man alle Pfadangaben korrigieren. Das heißt ich als Windows> User korrigiere die Pfadangaben erstmal primär für potentielle Linuxer.
Das eigentlich nicht direkt mit Linux zu tun. Es gibt eigentlich nur die
folgenden Dinge, die wesentlich sind:
- Verwendest du /, dann ist das nach C-Standard zwar
implementationsspezifisch (was die headernamen aber eh immer sind), aber
es ist ok. Es funktioniert auf so ziemlich allem, was den Compiler
ausführen kann, und das geht auch über Linux hinaus (z.B. MacOS,
FreeBSD, Solaris, …)
- Wenn du dagegen \ verwendest, ist das nach C-Standard und C++ vor
C++23 offiziell undefiniertes Verhalten. Es funktioniert außerdem
ausschießlich unter Windows. Irgendeinen Vorteil gegenüber der anderen
Variante hat es nicht.
Dazu kommt noch, dass das mit dem \ ja so nur bei #include funktioniert.
Beim Öffnen von Dateien dagegen tut's dann (mit String literals) so
nicht mehr.
Rolf M. schrieb:> Beim Öffnen von Dateien dagegen tut's dann (mit String literals) so> nicht mehr.
… oder man müsste dann generell alle Backslashes doppelt notieren, das
wäre wieder sicher. Vorwärtsstriche sind dann sicherlich die einfachere
(und besser lesbare) Variante. ;-)
Zino schrieb:> Illustration von "undefined behavior":> http://www.catb.org/jargon/html/N/nasal-demons.html
Ja, kenn ich noch. Ich war zwar glaub noch nicht dabei, als das
entstanden ist, aber kurz danach. Hab selbst oft genug in comp.lang.c
"Neulingen" von nasalen Dämonen erzählt … mann, bin ich alt. 🤔