Multi-Byte Zeichen vergleichen?
-
In dem Fall könnte man auch 2 Zeichen vergleichen. Pointer auf das erste übergeben, vergleichen, erhöhen, vergleichen.
-
inline bool twobytescmp(char *ptr) { return *ptr == 'l' && *(ptr+1) == 'o'; }Sry falls ein Bug drinnen ist denke so passt es.
-
Ethon schrieb:
(...)
Und da liegt mein Problem:
bool is_ae(char c) { return c == 'ä'; }Das kann ja nicht funktionieren? Was bleibt mir an Optionen außer einem direkten Stringvergleich? Denn eine solche Funktion muss mit Iteratorenpaaren auskommen ...
Mal angenommen dass du bereits irgendwo sicherstellst dass das was der Lexer verarbeitet gültiges UTF-8 ist, und z.B. nicht mit irgendwas aufhört wo laut Byte N noch ein Byte N+1 folgen müsste, aber Byte N schon das letzte ist... dann ...
bool is_ae(char* p) { return decode_utf8(p) == Unicode_ae; }Tadaaa
Sonst könntest du noch den Text während der Bearbeitung in UCS-4 verwandeln. z.B. über spezielle "Iteratoren", die zwar intern mit (unsigned) char-Zeigern arbeiten, aber beim Dereferenzieren/Inkrementieren/... das UTF-8 Encoding berücksichtigen. Also beim Lesen immer nen UCS-4 Wert zurückgeben und beim Inkrementieren eben um einem kompletten Codepoint weiterrücken.
Obwohl hier etwas "Range-artiges" vermutlich besser wäre, weil leichter zu implementieren und u.U. auch leichter zu handhaben.Oder du bleibst einfach bei UCS-4 und konvertierst vorher alles im RAM.
-
Oder man macht sich eine Klasse Char, die mehrere char enthält, statt überall char* rum zu werfen.
-
Ginge es denn nicht mit Templates?
template<typename ch_t> bool is_ae(ch_t c) { return c == static_cast<ch_t>('\204'); }
-
Hacker schrieb:
Ginge es denn nicht mit Templates?
template<typename ch_t> bool is_ae(ch_t c) { return c == static_cast<ch_t>('\204'); }Schau dir mal an was UTF-8 ist.
http://www.utf8-zeichentabelle.de/ Suche das ä.
-
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.An dieser Stelle nicht. Der Code ist kein template und es gibt keinen Hinweis darauf, dass der Code innerhalb einer Klasse steht. Ohne inline führt das nach ODR zu Linkerfehlern.
The more you know.
-
pschiuuuuuuu schrieb:
Oder man macht sich eine Klasse Char, die mehrere char enthält, statt überall char* rum zu werfen.
Aber das macht ja schon wchar_t.
Okay, ihr habt mich überzeugt, ich versuche einfach nicht mehr normale chars zu supporten, danke (besonders an hustbaer).
-
wchar_t ist auch nur bedingt geeignet, denn GCC/Linux meint dass wchar_t 4 Byte breit ist, MSVC/Windows meint dass wchar_t 2 Byte breit ist.
Nimm (u)int32_t.
-
otze schrieb:
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.[...]
Ohne inline führt das nach ODR zu Linkerfehlern.So pauschal ist das nicht richtig. Ich habe in meinen Codes jede freier Funktionen ohne das Schlüsselwort inline deklariert und definiert ohne Linkerfehler zu bekommen.
-
Belli schrieb:
otze schrieb:
Hacker schrieb:
Das
constgibt keine Sicherheit,inlineist unnötig.[...]
Ohne inline führt das nach ODR zu Linkerfehlern.So pauschal ist das nicht richtig. Ich habe in meinen Codes jede freier Funktionen ohne das Schlüsselwort inline deklariert und definiert ohne Linkerfehler zu bekommen.
Und die waren in Header-Dateien?
-
Nö, wieso sollten sie? Steht hier etwa irgendwo, dass die hier in Rede stehende Funktion in einer Header-Datei ist?
Edit: Die Deklarationen waren in Header-Dateien, die Definitionen nicht ... ist das nicht der übliche Weg?
-
"nach ODR zu Linkerfehlern" ist doch sowieso quatsch.
Der Standard kennt die ODR, aber keine Linker.
Bei ODR violations sind auch "no diagnostics required".
-
hustbaer schrieb:
"nach ODR zu Linkerfehlern" ist doch sowieso quatsch.
Der Standard kennt die ODR, aber keine Linker.
Bei ODR violations sind auch "no diagnostics required".*seufz* *reicht dir eine Korinthe*
-
Naja, es is halt doof wenn man davon ausgeht dass man nen Fehler bekommt wenn man was falsch macht, aber eben keinen bekommt.
Wie es z.B. passiert wenn man ne Inline Funktion in mehreren Übersetzungseinheiten unterschiedlich definiert.Das ist nämlich auch ne ODR Verletzung. Dem Compiler/Linker ist das bloss vollkommen egal, die prüfen das nicht.
-
Edit: stopp. irgendwas ist faul.
-
hustbaer schrieb:
Das ist nämlich auch ne ODR Verletzung. Dem Compiler/Linker ist das bloss vollkommen egal, die prüfen das nicht.
Okay, das ist mir neu. Ich dachte eigentlich, dass der Linker nur nach den Symbolen sucht und dann doppelte Symbole als Fehler ausspuckt.(er muss ja mindestens einmal alle Symbole anschauen um die Sprungaddressen richtig hinzukriegen) In dem Sinne ist dein Einwand nützlich. Aber ich denke, dass diese Fehlerquelle so selten ist, dass man sie im Vergleich zu einem fehlenden inline erstmal vernachlässigen kann. Ich würde das eher zur DLL-hell zählen.
Im Vergleich dazu fand ich den Einwand mit dem Linker halt doch etwas kleinlich. Es ist schwer, sich ein Übersetzungsmodell für C++ ohne Linker vorzustellen.
-
Das hat nix mit "DLL hell" zu tun, DLLs sind hier keine im Spiel.
Beispiel:
// a.cpp ---------------------------------------------------------- #include <iostream> inline int fib(int x) { if (x > 1) return fib(x - 1) + fib(x - 2); else return x; } void a(int x) { std::cout << "a: " << fib(x) << std::endl; } void b(int x); int main() { a(7); b(7); } // b.cpp ---------------------------------------------------------- #include <iostream> // wäre OK, wenn die definition equivalent zu der in a.cpp wäre inline int fib(int x) { if (x > 1) return fib(x - 1) + fib(x - 2) + 1; // bah, FEHLER else return x; } void b(int x) { std::cout << "b: " << fib(x) << std::endl; }Was meinst du was das Programm ausgibt? Bei mir (VC10) kompiliert das einwandfrei, linkt einwandfrei, und der Output ist
a: 33 b: 33Dreh die Reihenfolge der .obj Files beim Linken um, und du wirst vermutlich
a: 13 b: 13bekommen.
-
ich zitiere mich mal:
Aber ich denke, dass diese Fehlerquelle so selten ist, dass man sie im Vergleich zu einem fehlenden inline erstmal vernachlässigen kann. Ich würde das eher zur DLL-hell zählen.
Heißt: Ich bezweifle, dass es diesen Fehler in der freien Wildbahn gibt, außer wenn man aus irgendeinem Grund merkwürdig linken muss, um das Programm zum laufen zu kriegen (Abhängigkeit x linkt statisch gegen foo.a.3.1 und Abhängigkeit y gegen dynamisch gegen foo.so.3.2)