divide and conquer / size_t und size_type / Bezeichner von Konstanten
-
manni66 schrieb:
Probier das mal aus:
warning C4245: 'argument' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
Wenn der user zu blöd ist, Warnungen zu beachten, hat er selber schuld
-
pumuckl schrieb:
warning C4245: 'argument' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
Wenn der user zu blöd ist, Warnungen zu beachten, hat er selber schuld
Das stimmt. Leider hängen die Warnungen aber von Compiler und den Warnungseinstellungen ab. Der g++ auf dem Mac ist da mit -Wall aber z.B. schweigsam.
Wenn man unsigned nimmt, kann man dann in der Funktion nicht mehr testen, ob der Wert richtig übergeben wurde.Signed/unsigned hat halt so seine tücken ...
-
manni66 schrieb:
Der g++ auf dem Mac ist da mit -Wall aber z.B. schweigsam.
Urgs. Das ist übel imo. Signed/unsigned mismatch ist doch ein relativ oft anzutreffendes Problem das durchaus zu Fehlern führen kann. d.h. zusätzlich zum gcc sollte man noch ne statische Codeanalyse drüberlaufen lassen
-
Ich beziehe meine Aussagen jetzt ausschließlich auf meine privaten Projekte, oder die Programmteile die ich komplett neu in Projekte einbringe.
Gugelmoser schrieb:
1. divide and conquer: Ich frage mich oft, ab wann es Sinn macht, Dinge auszulagern. Macht es z.B. Sinn, eine Benutzereingabe oder die Ausgabe der Vektorelemente auszulagern? Wie macht ihr das?
Ja es macht Sinn. Eine Klasse sollte eine Aufgabe haben, und eine Ausgabe hat nichts mit einem Container zu tun. Falls man dieses miteinander integriert führt das meiner Erfahrung nach eigentlich immer über kurz oder lang zu Problemen (z.B. weil eine andere Form von Ausgabe oder ein anderes Ausgabeziel dazu kommt...).
Gugelmoser schrieb:
2. size_t und size_type: Verwendet ihr bzgl. Container der STL size_t oder size_type? Verwendet ihr, wenn etwas nicht <0 werden kann, einen unsigned Typen?
Ja, wozu unnötige Fehlerquellen oder Konvertierungen einbauen?
Gugelmoser schrieb:
3. Bezeichner von Konstanten: Schreibt ihr diese immer in Großbuchstaben? Falls ja, wie macht ihr es mit konstante Objekte, konstante Zeiger oder Referenzen auf konstante Variablen/Objekte?
Für mich gibt es kein Unterschied zwischen Konstanten und anderen Typen. Einzig globale Konstanten stehen bei mir in Großbuchstaben, und sind meist ein Zeugnis eines übernommenen Code mit ursprünglich Makros als Konstanten.
-
pumuckl schrieb:
manni66 schrieb:
Der g++ auf dem Mac ist da mit -Wall aber z.B. schweigsam.
Urgs. Das ist übel imo. Signed/unsigned mismatch ist doch ein relativ oft anzutreffendes Problem das durchaus zu Fehlern führen kann. d.h. zusätzlich zum gcc sollte man noch ne statische Codeanalyse drüberlaufen lassen
Probier mal -Wsign-conversion
(Keine Ahnung warum es nicht Default ist ... Jemand auf Stackoverflow sagte, es wäre ein Feature von C ...)
-
gcc 4.6.2 Manual schrieb:
-Wconversion
Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like abs (x) when x is double; conversions between signed and unsigned, like unsigned ui = -1; and conversions to smaller types, like sqrtf (M_PI). Do not warn for explicit casts like abs ((int) x) and ui = (unsigned) -1, or if the value is not changed by the conversion like in abs (2.0). Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion.For C++, also warn for confusing overload resolution for user-defined conversions; and conversions that will never use a type conversion operator: conversions to void, the same type, a base class or a reference to them. Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
[...]
-Wsign-conversion
Warn for implicit conversions that may change the sign of an integer value, like assigning a signed integer expression to an unsigned integer variable. An explicit cast silences the warning. In C, this option is enabled also by -Wconversion.Keine dieser Optionen wird durch -Wall oder -Wextra aktiviert.
-
Warum die nicht durch -Wall oder -Wextra aktiviert wird, habe ich mich auch schon gefragt
-
brotbernd schrieb:
Gugelmoser schrieb:
Verwendet ihr, wenn etwas nicht <0 werden kann, einen unsigned Typen?
i.d.R. ja.
Ist es angebracht, dann einfach immer size_t zu benutzen?
-
Gugelmoser schrieb:
Ist es angebracht, dann einfach immer size_t zu benutzen?
Nein. size_t hat eine besondere Semantik: Es ist speziell für Speichergrößen und positionen im Speicher gedacht. Für Sachen wie: "wie viele gerade zahlen gibt es in diesem Array" würde ich daher als Ergebniswert unsigned nehmen.
-
Ich persönlich mag
size_t
nicht. Es führt neue integrale Typen in C++ ein und macht Code inkonsistenter. Alleine schon die beiden Frontensize_t
undstd::size_t
... Ausserdem benötigt man dazu einen Header (auch wenn dieser meist indirekt eingebunden wird).Und
std::vector::size_type
ist ganz schlimm, erneut ein Stück Generizität für gar nichts. Es schafft wieder die Notwendigkeit neuer Konvertierungen, wobei die Fehleranfälligkeit bei solch intransparententypedef
s lediglich steigt.Betrachtet man nur aktuelle Architekturen, fände ich
unsigned int
als Standardlösung gar keinen so schlechten Kompromiss.otze schrieb:
Nein. size_t hat eine besondere Semantik: Es ist speziell für Speichergrößen und positionen im Speicher gedacht. Für Sachen wie: "wie viele gerade zahlen gibt es in diesem Array" würde ich daher als Ergebniswert unsigned nehmen.
Hier fängts schon an. Vergleiche mal die Rückgabetypen von
std::vector::size()
,std::count()
und deinerAnzahlGeradeZahlen()
-Funktion. 3 verschiedene Typen, um eine Anzahl zu erhalten. Das kanns doch nicht sein.
-
otze schrieb:
Für Sachen wie: "wie viele gerade zahlen gibt es in diesem Array" würde ich daher als Ergebniswert unsigned nehmen.
Mir scheint der Wertebereich hierfür ist der der Größe des Arrays, und somit unmittelbar mit size_t verknüpft.
-
otze schrieb:
Gugelmoser schrieb:
Ist es angebracht, dann einfach immer size_t zu benutzen?
Nein. size_t hat eine besondere Semantik: Es ist speziell für Speichergrößen und positionen im Speicher gedacht. Für Sachen wie: "wie viele gerade zahlen gibt es in diesem Array" würde ich daher als Ergebniswert unsigned nehmen.
Des können aber ein guter Haufen mehr sein als in einen "unsigned" reinpassen.
"unsigned" ist mit MSVC (sowie vermutlich allen anderen Windows Compilern) und Target = x64 nämlich 32 Bit gross. Genau so wie long dort immer noch 32 Bit gross ist.
Nur um ein Beispiel zu nennen.
-
hustbaer schrieb:
Nur um ein Beispiel zu nennen.
dann mach unsigned long draus. An der Semantik ändert das 0.
-
otze schrieb:
hustbaer schrieb:
Nur um ein Beispiel zu nennen.
dann mach unsigned long draus. An der Semantik ändert das 0.
Hä? Was soll das helfen?
unsigned long ist mit MSVC/64 Bit auch nur 32 Bit gross (genau wie bei MSVC/32 Bit).
Du müsstest schon unsinged long long nehmen.
Nur unsinged long long könnte wieder grösser als nötig sein, z.B. weil es auf 32 Bit Systemen auch 64 Bit hat.size_t ist so gross, wie "Dinge" im Speicher platz haben.
-> size_t ist für sowas genau das Richtige.Wieso kompliziert, wenns einfach auch geht?
-
hustbaer schrieb:
Wieso kompliziert, wenns einfach auch geht?
? Du glaubst doch nicht ernsthaft, dass die letzten 4 Posts von mehr als nur akademischen Interesse sind?
-
Schauen wir uns an, wieviele Tage seit der Geburt Jesu' vergangen ist: Garantiert unsigned.
Aber bilden wir uns nicht zuviel auf unsere Software und deren Einsatz in der Zukunft ein? Sollen wir wirklich einen 64-bitter zurückzugeben?
Ich denke schon.
-
hustbaer schrieb:
Wieso kompliziert, wenns einfach auch geht?
Finde ich auch. Deswegen benutze ich kein unsigned mehr.
-
otze schrieb:
hustbaer schrieb:
Wieso kompliziert, wenns einfach auch geht?
? Du glaubst doch nicht ernsthaft, dass die letzten 4 Posts von mehr als nur akademischen Interesse sind?
Klar sind sie das.
Du glaubst doch nicht ernsthaft dass ich dich jetzt noch ernst nehmen kann?