partielle Template Spezialisierung multi-dimension C-arrays

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Krishty hat geschrieben: Und &((int*)pArray) gleicht dem klareren ((int*)pArray) + i.

Nein, es gleicht ((int*)pArray) + i*sizeof(int) und dabei kann man der Einfachheit halber den Cast auch weglassen und direkt pArray+i*sizeof(int) schreiben, um den Code leserlicher zu machen.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Aramis »

Der Zugriff auf ein Array ist (wenn nicht ueberschrieben) definiert wie folgt:

Code: Alles auswählen

T a[] = {...};
dann gilt: a[i] == &a[0]+i == a+i  

ergo: &((int*)pArray)[i] == ((int*)pArray) +i 
((int*)pArray) + i*sizeof(int) wuerde jeweils auf das i*sizeof(int)te Element zugreifen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

kaiserludi hat geschrieben:
Krishty hat geschrieben: Und &((int*)pArray) gleicht dem klareren ((int*)pArray) + i.

Nein, es gleicht ((int*)pArray) + i*sizeof(int)
Nein tut es nicht. Was du schreibst, überspringt bei jedem Zugriff eine Anzahl von sizeof(int) - 1 Elemente des Arrays. Die Umwandlung von &(x[y]) zu x + y steht afaik sogar 1:1 so im Standard.

int * toIntArray;
assert((toIntArray + 1) == &(toIntArray[1])); // true
assert((toIntArray + 2) == &(toIntArray[2])); // true

kaiserludi hat geschrieben:So was darf ich öfter lesen
Das liest du garantiert nie, weil es falsch ist. ((void*)x)+y gibt es nicht. Da ändert auch der Pseudo-Text nichts dran.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Aramis »

Korrekt, Pointer-Arithmetik auf void*-Pointern gibt es nicht.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

Und noch einer hinterher:
ptr + i hat man zu lesen als ptr um i Elemente verschoben. Einfacher geht es wirklich nicht mehr.

Die einzigen Element-Typen, mit denen man auf Bytes arbeiten kann, sind char und unsigned char (wobei ich mir bei letzterem nicht sicher bin).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Krishty hat geschrieben:Und noch einer hinterher:
ptr + i hat man zu lesen als ptr um i Elemente verschoben. Einfacher geht es wirklich nicht mehr.

Die einzigen Element-Typen, mit denen man auf Bytes arbeiten kann, sind char und unsigned char (wobei ich mir bei letzterem nicht sicher bin).
Also ich finde ptr als i-tes Element von ptr einfacher.
Meines Wissens nach schreibt der Standard vor, dass char, signed char und unsigned char identisch groß sein müssen, schreibt aber nicht vor, wie viele bytes es exakt sein müssen. Übrigens sind char und signed char nicht identisch, auch nicht auf Plattformen, auf den char vorzeichenbehaftet ist, im Gegensatz zu short oder int, die identisch zu signed short und signed int sind, gibt es bei char 3 Datentypen: char, signed char und unsigned char. Wenn man also mit char und unsigned char auf byteebene arbeiten kann, dann sollte es auch mit signed char gehen.

So, habe gerade mal durchgetestet und folgendes durch den GCC gejagt:

Code: Alles auswählen

    int arr[5] = {0, 1, 2, 3, 4};
    void* a = arr;
    for(int i=0; i<5; i++)
        printf("%d ", *(int*)(a+i));
    printf("\n");
    for(int i=0; i<5; i++)
        printf("%d ", *(int*)(a+i*sizeof(int)));
    printf("\n");
Ausgabe ist:
0 16777216 65536 256 1
0 1 2 3 4

Code: Alles auswählen

    int arr[5] = {0, 1, 2, 3, 4};
    void* a = arr;
    for(int i=0; i<5; i++)
        printf("%d ", *((int*)a+i));
    printf("\n");
    for(int i=0; i<5; i++)
        printf("%d ", *((int*)a+i*sizeof(int)));
    printf("\n");
hingegen liefert
0 1 2 3 4
0 4 195028 94640000 12
Worauf ihr euch bezieht ist der zweite Fall. Der erste hingegen funktioniert nur mit dem sizeof korrekt.
Allerdings durfte ich gerade mit Erschrecken feststellen, dass der erste Code aus einem unix-platformlayer ist und mir deswegen nie aufgefallen ist, dass er in Visual C++ überhaupt nicht kompiliert.
Dabei kompiliere ich doch im GCC schon bewusst mit -std=C99, damit er nur standardkonformen Code zulässt...
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Aramis »

Siehe auch http://codepad.org/dxG0wTNY fuer das erste und http://codepad.org/aghmcbkd fuer das zweite Snippet.
gcc hat geschrieben:error: pointer of type 'void *' used in arithmetic
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von dot »

kaiserludi hat geschrieben:Meines Wissens nach schreibt der Standard vor, dass char, signed char und unsigned char identisch groß sein müssen, schreibt aber nicht vor, wie viele bytes es exakt sein müssen.
Doch der Standard definiert sizeof(char) == 1. Die Größe von einem Byte ist aber nicht definiert, es müssen nur mindestens 8 Bit sein.
Zuletzt geändert von dot am 29.03.2011, 18:59, insgesamt 2-mal geändert.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

kaiserludi hat geschrieben:Also ich finde ptr als i-tes Element von ptr einfacher.
Ja, aber du willst ja nicht das Element, sondern einen Zeiger darauf. Und wenn & davorkommt muss man im Zweifelsfall erst nachschlagen, ob &ptr[j] als (&ptr)[j] oder als &(ptr[j]) behandelt wird. Ich weiß es z.B. vom Draufschauen nicht, obwohl ich mich mal intensiv damit auseinandergesetzt hatte. Und ich hasse zwei Operatoren auf demselben Ausdruck.
kaiserludi hat geschrieben:Meines Wissens nach schreibt der Standard vor, dass char, signed char und unsigned char identisch groß sein müssen, schreibt aber nicht vor, wie viele bytes es exakt sein müssen.
Nein – der Standard schreibt vor, dass char die Größe der kleinsten adressierbaren Einheit hat. Auch ein Byte ist als kleinste adressierbare Einheit definiert; darum ist char immer automatisch 1 Byte groß. Bytes im Sinne von 8-Bit-Gruppen wären Oktetts; wie viele Oktetts ein char groß ist, weiß man nicht.
Weiterhin schreibt der Standard afaik nicht vor, dass signed char und unsigned char dieselbe Größe wie char haben, sondern nur, dass sie den entsprechenden Wertebereich unterstützen. Darum bin ich mir bei unsigned char auch nicht sicher, ob er zur Byte-weisen Adressierung taugt; aber in den Aliasing-Regeln ist er explizit als überlappend zugelassen, was eigentlich dafürspricht.

Wiedemauchsei: void *-Arithmetik geht in C++ nicht. Ich muss erstmal nachschlagen, ob es in C99 zulässig ist, und ob GCC es deshalb durchgehen lässt. Und selbst, falls es gehen sollte, verletzt es die Aliasing-Regeln und alles, was du tust, ist undefiniert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von dot »

@dot: Du hast die Autoren verwechselt ;)
oops, habs ausgebessert
Krishty hat geschrieben:Nein – der Standard schreibt vor, dass char die Größe der kleinsten adressierbaren Einheit hat. Auch ein Byte ist als kleinste adressierbare Einheit definiert; darum ist char immer automatisch 1 Byte groß. Bytes im Sinne von 8-Bit-Gruppen wären Oktetts; wie viele Oktetts ein char groß ist, weiß man nicht.
Korrekt, der Standard sagt aber nichts darüber aus wieviele Bits ein Byte hat, es müssen lediglich mindestens 8 sein, die genaue Anzahl ist über das Makro CHAR_BIT zugänglich und muss nicht unbedingt ein Vielfaches von 8 sein (alles >= 8 ist möglich).
Krishty hat geschrieben:Weiterhin schreibt der Standard afaik nicht vor, dass signed char und unsigned char dieselbe Größe wie char haben, sondern nur, dass sie den entsprechenden Wertebereich unterstützen. Darum bin ich mir bei unsigned char auch nicht sicher, ob er zur Byte-weisen Adressierung taugt; aber in den Aliasing-Regeln ist er explizit als überlappend zugelassen, was eigentlich dafürspricht.
Doch der Standard schreibt für char und alle unsigned Typen vor dass sie die selbe Größe und die selben Alignmentkriterien haben wie die entsprechenden signed Typen, der Standard spricht an der Stelle sogar von "gleichen Objektrepräsentationen".
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

dot hat geschrieben:
Krishty hat geschrieben:Weiterhin schreibt der Standard afaik nicht vor, dass signed char und unsigned char dieselbe Größe wie char haben, sondern nur, dass sie den entsprechenden Wertebereich unterstützen. Darum bin ich mir bei unsigned char auch nicht sicher, ob er zur Byte-weisen Adressierung taugt; aber in den Aliasing-Regeln ist er explizit als überlappend zugelassen, was eigentlich dafürspricht.
Doch der Standard schreibt für char und alle unsigned Typen vor dass sie die selbe Größe und die selben Alignmentkriterien haben wie die entsprechenden signed Typen, der Standard spricht an der Stelle sogar von "gleichen Objektrepräsentationen".
Hast recht:
§5.3.3 aus dem C++0x-Draft hat geschrieben:sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1.
(Wobei ich nicht weiß, ob das in C++97 auch schon so war.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

dot hat geschrieben:@dot: Du hast die Autoren verwechselt ;)
oops, habs ausgebessert
Krishty hat geschrieben:Nein – der Standard schreibt vor, dass char die Größe der kleinsten adressierbaren Einheit hat. Auch ein Byte ist als kleinste adressierbare Einheit definiert; darum ist char immer automatisch 1 Byte groß. Bytes im Sinne von 8-Bit-Gruppen wären Oktetts; wie viele Oktetts ein char groß ist, weiß man nicht.
Korrekt, der Standard sagt aber nichts darüber aus wieviele Bits ein Byte hat, es müssen lediglich mindestens 8 sein, die genaue Anzahl ist über das Makro CHAR_BIT zugänglich und muss nicht unbedingt ein Vielfaches von 8 sein (alles >= 8 ist möglich).
Krishty hat geschrieben:Weiterhin schreibt der Standard afaik nicht vor, dass signed char und unsigned char dieselbe Größe wie char haben, sondern nur, dass sie den entsprechenden Wertebereich unterstützen. Darum bin ich mir bei unsigned char auch nicht sicher, ob er zur Byte-weisen Adressierung taugt; aber in den Aliasing-Regeln ist er explizit als überlappend zugelassen, was eigentlich dafürspricht.
Doch der Standard schreibt für char und alle unsigned Typen vor dass sie die selbe Größe und die selben Alignmentkriterien haben wie die entsprechenden signed Typen, der Standard spricht an der Stelle sogar von "gleichen Objektrepräsentationen".
Interessant. Ich wusste nicht, dass 8bit Midnestgröße vorgeschrieben sind. Ich dachte immer, man könnte als Compilerentwickler z.B. ein Byte auch 7Bit groß wählen.
Krishty hat geschrieben:
dot hat geschrieben:
Krishty hat geschrieben:Weiterhin schreibt der Standard afaik nicht vor, dass signed char und unsigned char dieselbe Größe wie char haben, sondern nur, dass sie den entsprechenden Wertebereich unterstützen. Darum bin ich mir bei unsigned char auch nicht sicher, ob er zur Byte-weisen Adressierung taugt; aber in den Aliasing-Regeln ist er explizit als überlappend zugelassen, was eigentlich dafürspricht.
Doch der Standard schreibt für char und alle unsigned Typen vor dass sie die selbe Größe und die selben Alignmentkriterien haben wie die entsprechenden signed Typen, der Standard spricht an der Stelle sogar von "gleichen Objektrepräsentationen".
Hast recht:
§5.3.3 aus dem C++0x-Draft hat geschrieben:sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1.
(Wobei ich nicht weiß, ob das in C++97 auch schon so war.)
C++ 97?
Gibt es nicht nur C++ 98, C++ 03 und C++ 0x und alles vor C++ 98 war nicht offiziell standadisiert?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

kaiserludi hat geschrieben:
Krishty hat geschrieben:(Wobei ich nicht weiß, ob das in C++97 auch schon so war.)
C++ 97?
Gibt es nicht nur C++ 98, C++ 03 und C++ 0x und alles vor C++ 98 war nicht offiziell standadisiert?
Stimmt, der Standard ist von ’98. Ich hatte einfach schnell auf das __cplusplus-Makro in VC geguckt, und das ist auf November ’97 datiert … weird.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Krishty hat geschrieben:
kaiserludi hat geschrieben:
Krishty hat geschrieben:(Wobei ich nicht weiß, ob das in C++97 auch schon so war.)
C++ 97?
Gibt es nicht nur C++ 98, C++ 03 und C++ 0x und alles vor C++ 98 war nicht offiziell standadisiert?
Stimmt, der Standard ist von ’98. Ich hatte einfach schnell auf das __cplusplus-Makro in VC geguckt, und das ist auf November ’97 datiert … weird.
C++ wurde ja ab 1979 entwickelt und die erste Referenzversion erschien 1985. Entsprechend muss natürlich schon vieles vor der ersten Standadisierung 1998 da gewesen sein.
Ich weiß das aber auch nur, weil ich mich letzte Woche damit rumschlagen durfte, welche C Standards und welche C++ Standards es gibt, weil interssanterweise Code, welcher im Default C-Modus von Visual Studio kompiliert, im GCC unter C99 kompiliert, aber nicht unter C89, obwohl Visual Studio im Default (keien Ahnung, ob man bei Visual Studio auch irgendwie den Standard setzen kann) gar nicht alle C99 Features unterstützt, während er im MinGW auch nicht unter C99 kompiliert, sondern nur mit GNU99 (so viel zu Thema, MinGW als GCC-Windows-Port). Durfte dann auch erst einmal mit Erschrecken feststellen, dass C++ erst ab C++0x die C99 Änderugnen offiziell unterstützt und in Version C++98 nur auf C89 basiert. Ein Wunder, dass das bei mir in der Praxis noch nicht zu Inkompatibilitäten geführt hat zwischen C-Lib und C++ Wrapper.
Zuletzt geändert von kaiserludi am 29.03.2011, 21:22, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

§16.0 hat geschrieben:__cplusplus
The name __cplusplus is defined to the value 199711L when compiling a C++ translation unit.*
[Footnote: It is intended that future versions of this standard will replace the value of this macro with a greater value. Non-conforming compilers should use a value with at most five decimal digits. --- end foonote]
Es ist also tatsächlich so, dass sich der 98er Standard als von November 1997 identifiziert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Krishty hat geschrieben:
§16.0 hat geschrieben:__cplusplus
Non-conforming compilers should use a value with at most five decimal digits.
Was bringt das denn, das festzulegen? Entwede habe ich das Makro schon vor dem Standard auf einen anderen Wert definiert und kann es aus Abwärtskompatibilitätsgründen nicht mehr ändern, dann aknn ich es aber auch icht auf einen mindestens 5-stelligen Wert ändern ,wenn der bisherige maximal 4 stellig ist, oder aber ich habe es noch nicht vor dem Standard definiert, dann habe ich aber auch keinen Grund, es nicht standardkonform zu definieren.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

at most == maximal. Nicht minimal (at least). Wenn man also vorher nicht mehr als fünf Ziffern besetzt hatte, was bei den meisten Compilern der Fall sein dürfte (_MSC_VER-mäßig), hat man Glück. Ansonsten eben Pech – Standards dienen dem kleinsten gemeinsamen Nenner und nicht dazu, dass jeder weiterhin sein eigenes Süppchen kochen kann.

GCC hat das Problem mit der Abwärtskompatibilität; bei denen ist __cplusplus einfach nur 1. War die erste Zeile meines Programms und gab beim Portieren sofort einen Fehler. Da kann ich garnicht genug kotzen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Stimmt, maxximal, aber ann gilt das von mir gesagte eben für Nummern über 5 Stellen: Wer in der Lage ist, seine über 5-stellige Nummer zu ändern, der kann sie genauso gut gleich standardkonform machen.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

Nein, afaik gilt das #define nur für tatsächlich weitestgehend dem kompletten Standard konforme Compiler – mir ist z.B. kein aktueller Compiler bekannt, der die Nummer bereits auf 2011xx gesetzt hat, obwohl alle mehr oder weniger C++0x-Features unterstützen. Wenn man also wichtige Klauseln nicht befolgt, sollte man lieber bei seiner fünfstelligen Zahl bleiben, damit die Quelltexte direkt wissen, dass was faul ist.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Ja, aber wer dem Standard in dem Punkt nicht folgt, der folgt ihm veilleicht auch in der Anmerkung nicht, wesewegen es wohl eh nur Sinn amcht, die Konstannte auf Gleichheit/Ungleichheit zu checken und nicht auf <= 99999 bzw. >99999. Auch wäre ein icht standardkonformer Compiler ja konform zu der Anmerkung, wenn er die Konstante auf einen 5stelligen Wert setzt, der größer als der Wert im Standard ist.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Interssant:
Folgender Code wird von VS anstandslos akzeptiert, wirft im GCC aber einen Haufen Fehler:

Code: Alles auswählen

	template<class CType> struct ConfirmAllowed<const CType>
	{
		typedef typename const ConfirmAllowed<CType>::type type;
		typedef typename const ConfirmAllowed<CType>::scalarType scalarType;
		static const unsigned int dimensions = ConfirmAllowed<CType>::dimensions;
		static const nByte typeName = ConfirmAllowed<CType>::typeName;
	};
Folgender Code hingegen wird auch vom GCC akzeptiert:

Code: Alles auswählen

	template<class CType> struct ConfirmAllowed<const CType>
	{
		typedef const typename ConfirmAllowed<CType>::type type;
		typedef const typename ConfirmAllowed<CType>::scalarType scalarType;
		static const unsigned int dimensions = ConfirmAllowed<CType>::dimensions;
		static const nByte typeName = ConfirmAllowed<CType>::typeName;
	};
Der einzige Unterschied ist "typename const" vs "const typename".
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

Ins Blaue geraten: Wenn du eh const davorschreibst (so sinnlos das auch ist), ist der Compiler dann nicht sowieso in der Lage, das als abhängigen Typen zu erkennen und zu verarbeiten? D.h. ist typename dann nicht überflüssig?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Nein, ist er nicht, aber das mit der Sinnlosigkeit ist ein gutes Stichwort, jetzt wo ich noch mal drüber nachdenke.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

Ich weiß echt nicht, was ich von C++’ typename halten soll :/ Jedenfalls zur Ursache: const dient als Dekoration für Typnamen, typename ist aber kein Typname. typedef hingegen schon. Bei typedef typename const versteht es der Compiler als Dekoration des typename durch const miss (kann man das Verb so teilen?), was nicht geht; bei typedef const typename als Dekoration des typename, was wiederum geht. Ein Grund mehr, const immer als Postfix zu schreiben.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Aber ist die Regel für const nicht, wenn es links von dem const nichts gibt, worauf es angewandt werden kann, dann wird geprüft, ob es rechts was gibt?
Demnach müsste "typedef typename const ConfirmAllowed<CType>::type type;" doch gleichbedeutend mit "typedef typename ConfirmAllowed<CType>::type const type;" sein? Letzteres wird vom GCC auch akzeptiert.
wenn ich im VS "typedef typename const ConfirmAllowed<CType>::type const type;" schreibe, warnt er auch, dass ich const zweimal auf den gleichen Typnamen anwende, was dafür spricht, dass er die beiden const beide auf ConfirmAllowed<CType>::type anwendet, allerdings spuckt Vs die gleiche Warnung auch bei "typedef const typename const ConfirmAllowed<CType>::type type;" und bei "typedef const typename ConfirmAllowed<CType>::type const type;" aus und bei "typedef const typename const ConfirmAllowed<CType>::type const type;" sogar doppelt.

Bei typedef typename const versteht es der Compiler als Dekoration des typename durch const miss (kann man das Verb so teilen?)
Wieso nicht einfach "Bei typedef typename const missversteht es der Compiler als Dekoration des typename durch const"?
Habe diese Teilung zumindest noch nie gesehen, also wenn es ohne Fehlermeldung durch einen "Deutsche Sprache"-Compiler gehen sollte ;), dann wird es zumindest selten verwendet, in etwa wie die Schreibweise "i[array]".
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Aramis hat geschrieben:Siehe auch http://codepad.org/dxG0wTNY fuer das erste und http://codepad.org/aghmcbkd fuer das zweite Snippet.
gcc hat geschrieben:error: pointer of type 'void *' used in arithmetic
Um da drauf noch einmal zurück zu kommen.
Die Fehlermeldung schmeißt codepad im C++ Modus mit G++ als Compiler, da Codepad hier in den Parametern, die ses an den Compiler übergibt, angibt, dass keine GCC-Extensions verwendet werden sollen.
Kompiliert man das ganze hingegen in Codepad als C, bekommt man auch mit Codepad das Ergebnis, welches ich oben gepostet hatte, dass nämlich der sizeof da hin muss, damit das gewünschte Ergebnis produziert wird, da Codepad fürC-Code nicht die implizit genutzen GCC-Extensions deaktiviert, die selbst dann im gcc aktiv sind, wenn man kein gnu99, sondern c99 als Standard angibt, sofern man sie nicht explizit deaktiviert.

Im Gegensatz zu striktem Standard-C bzw. Standard-C++ definieren die GNU-Extensions nämlich tatsächlich void*-Arithmetic und zwar als byte-arithmetic:
wikipedia hat geschrieben: Pointer arithmetic cannot be performed on void pointers because the void type has no size, and thus the pointed address can not be added to, although gcc and other compilers will perform byte arithmetic on void* as a non-standard extension. For working "directly" with bytes they usually cast pointers to BYTE*, or unsigned char* if BYTE is not defined in the standard library used.
Quelle: http://en.wikipedia.org/wiki/Pointer_(c ... nd_C.2B.2B

EDIT:
Hmm, scheint nicht an Codepads Übergabeparametern zu liegen, sondern tatächlich nur in GCC standardmäßig aktiviert zu sein und nicht in G++.
Das ist auch interessant:
6.22 Arithmetic on void- and Function-Pointers

In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.

A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.

The option -Wpointer-arith requests a warning if these extensions are used.
Quelle: http://gcc.gnu.org/onlinedocs/gcc-4.5.0 ... nter-Arith
sizeof(void) LOL, die Leere hat die Größe 1 :shock:

EDIT 2:
Au Mann, VS kompiliert auch sizeof(void) in C ohne Error, nur mit Warning, dass sizeof 0 zurückgibt.
Netter Runtime-Compilercheck:

Code: Alles auswählen

compilertype = sizeof(void)?gcc:msvc;
:lol:
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

Omg. Jaa, das mit sizeof(void) ist drin, weil es die Metaprogrammierung erleichtert (derselbe Grund, aus dem man auch void voidFunc() { return notherVoidFunc(); } schreiben kann) – aber das mit der void *-Arithmetik und 1 == sizeof(void) zeigt ziemlich gut, was für Verwirrung man stiftet, wenn man „handliche“ Änderungen am Standard vornimmt.

Aber danke, dass du das rausgesucht hast – diese Erweiterung war mir komplett unbekannt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von kaiserludi »

Krishty hat geschrieben:Omg. Jaa, das mit sizeof(void) ist drin, weil es die Metaprogrammierung erleichtert (derselbe Grund, aus dem man auch void voidFunc() { return notherVoidFunc(); } schreiben kann) – aber das mit der void *-Arithmetik und 1 == sizeof(void) zeigt ziemlich gut, was für Verwirrung man stiftet, wenn man „handliche“ Änderungen am Standard vornimmt.

Aber danke, dass du das rausgesucht hast – diese Erweiterung war mir komplett unbekannt.
das mit dem return aVoidFunc() in einer void Funktion habe ich sogar erst letztens genutzt, hat einiges simplifiziert, weiß nur nicht mehr, wofür ich es eingesetzt habe. Gar nicht gewusst, dass das auch nicht standardkonform ist.

Habe heute zufällig beim Suchbegriff void*Arithmetik diese Info entdeckt, dass der GCC diese Erweiterung auch ohen GNU-Extensions standardmäßig aktiviert hat und mich daran erinnert, dass wir uns hier gewundert haben, wieso der für seine Standard-Konformität bekannte GCC das im C99-Mode kzeptiert, obwohl es nicht standardkonform ist.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: partielle Template Spezialisierung multi-dimension C-arr

Beitrag von Krishty »

kaiserludi hat geschrieben:das mit dem return aVoidFunc() in einer void Funktion habe ich sogar erst letztens genutzt, hat einiges simplifiziert, weiß nur nicht mehr, wofür ich es eingesetzt habe. Gar nicht gewusst, dass das auch nicht standardkonform ist.
Ich meinte genau andersherum, dass beides erlaubt sei, aber sizeof(void) ist, wie ich gerade feststelle, nicht erlaubt (weil void ein incomplete type ist).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten