🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
10 messages
10 total messages Started by Andrea Hermann Fri, 26 Jan 1996 17:49
void* - Felder
#1398
Author: Andrea Hermann
Date: Fri, 26 Jan 1996 17:49
28 lines
1153 bytes
Hi, 
ich habe hier ein Programmfragment, von dem ich nicht weiss,
wieso es nicht tut:

int main()
{
    void* feld;
    int   typ;

    // typ = 1 fuer int, 2 fuer double,...

    switch( typ )
    {
        case 1: f = ( void* ) new int[n];
                for( int i = 0; i < n; i++ )
                    ein >> (int)f[i];
                break;

        // andere Faelee
     }
     return 0;
}

Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...

Andrea
Re: void* - Felder
#1410
Author: Ullrich von Bassewitz
Date: Sat, 27 Jan 1996 00:11
24 lines
1141 bytes
Andrea Hermann (hermann@ipf.bau-verm.uni-karlsruhe.de) wrote:
>         case 1: f = ( void* ) new int[n];
>                 for( int i = 0; i < n; i++ )
>                     ein >> (int)f[i];
>                 break;

Aus Deinem Code geht nicht genau hervor, welchen Typ f hat. Wenn es ein
void* sein soll, dann ist klar, warum die Geschichte nicht tut:

f[i] ist undefiniert wenn f ein untypisierter Zeiger ist.

        ein >> ((int*)f)[i];

sollte tun. (Andererseits ist mir nicht ganz klar, warum Du hier mit void
Zeigern rummachst, vielleicht ist meine Annahme, f sei ein void Zeiger,
falsch).

Gruss


        Uz

-- 
Ullrich von Bassewitz                              uz@ibb.schwaben.com
Re: void* - Felder
#1432
Author: Karl-Heinz Krause
Date: Sat, 27 Jan 1996 09:59
36 lines
1166 bytes
Am 26. Jan. 1996 schrieb Andrea Hermann
(hermann@ipf.bau-verm.uni-karlsruhe.de):

> Hi, 
> ich habe hier ein Programmfragment, von dem ich nicht weiss,
> wieso es nicht tut:

> int main()
> {
>     void* feld;
>     int   typ;

>     // typ  fuer int, 2 fuer double,...

>     switch( typ )
>     {
>         case 1: f ( void* ) new int[n];
                  ^
Du meinst wohl:  feld new int[n];
Das explizite casten nach void* ist nicht erforderlich.

>                 for( int i ; i < n; i++ )
>                     ein >> (int)f[i];

richtig:  ein >> ((int*)feld)[i];

>                 break;

>         // andere Faelee
>      }
>      return 0;
> }



Karl-Heinz Krause
Re: void* - Felder
#1420
Author: Ralf W. Stephan
Date: Sat, 27 Jan 1996 12:09
13 lines
847 bytes
Andrea Hermann writes:
> Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
> Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
> wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...

Definiere eine union, in der alle Typen hineinpassen und feld
als Pointer auf die union.  Die C++ Lösung wäre, mit Containern
zu arbeiten, was auch wesentlich lesbarer und sicherer ist.


ralf
--
PGP: 1024/0xA713ECE9 2047/0xC8E605F5
Re: void* - Felder
#1417
Author: Dietmar Kuehl
Date: Sat, 27 Jan 1996 21:52
120 lines
4379 bytes
Hi,

Andrea Hermann (hermann@ipf.bau-verm.uni-karlsruhe.de) wrote:
: ich habe hier ein Programmfragment, von dem ich nicht weiss,
: wieso es nicht tut:

Gehe ich recht der Annahme, das "nicht tut" eigentlich meint "laesst
sich nicht compilieren"? Das koennte ich mir bequem vorstellen:

: int main()
: {
:     void* feld; 

Ist 'feld' identisch mit 'f'? ... oder ist 'f' ebenfalls als 'void*'
deklariert?

:     int   typ;

:     // typ = 1 fuer int, 2 fuer double,...

:     switch( typ )
:     {
:         case 1: f = ( void* ) new int[n];

Mal ganz davon abgesehen, dass man '(void*)' weglassen kann, da die
Konversion von Pointern nach 'void*' automatisch passiert, deutet die
ganze Sache auf einen (erheblichen) Designfehler hin:

  - nicht in eine Klasse eingekapselte built-in Arrays sind fuer mich
    bekanntlich sowieso ein rotes Tuch.
  - so wie 'f' benutzt wird, ist es viel zu gefaehrlich: Man kann leicht
    aus versehen mal den Falschen Cast verwenden und man laeuft in
    "undefined behavior".
  - wenn ein neuer Typ aufgenommen werden soll, muss in jedem 'switch' ein
    entsprechender 'case' aufgenommen werden. Ich vermute, dass hier,
    abhaengig von irgendeinem magischen Parameter, ein Vektor von
    Objekten eingelesen werden soll. Irgendwann wird man den magischen
    Parameter auswerten muessen (der vermutlich eher ein 'enum' anstatt
    einem 'int' sein sollte...), da fuehrt vermutlich kein Weg dran
    vorbei, aber dannach ist der Typ festgelegt. Was man also machen
    koennte, ist in einem 'switch' ein passendes Objekt erzeugen und
    das dann fuellen.

:                 for( int i = 0; i < n; i++ )
:                     ein >> (int)f[i];

Damit das mit dem 'void*' geht, muss diese Zeile so lauten:

		      cin >> ((int*)f)[i];

('ein' ist vermutlich ein Typo, oder?)

:                 break;

:         // andere Faelee
:      }
:      return 0;
: }

: Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
: Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
: wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...

Wen wunderts...: In dem Programm versuchst Du 'operator[]()' auf einen
'int' anzuwenden.  Aber der ist sicher nicht definiert (der Standard
definiert ihn nicht und der Benutzer kann ich nicht definieren, da
Operatoren fuer built-in Typen nicht ueberladen werden koennen). Hier
ist uebrigens mein Vorschlag:

// #include <iostream> nach Standard...
#include <iostream.h>
#include <vector>
#include <cstring>

template <class T> void read_vector(istream &in, vector<T> &vec, int dim)
{
  for (int i = 0; i < dim; i++)
    in >> vec[i];	// sollte eigentlich auch gechecked werden...
}

int main(int ac, char *av[])
{
  if (ac < 2)
  {
    cerr << "Usage: " << av[0] << " <type>\n";
    return 1;
  }

  int    dimension = 3;

  if (!strcmp(av[1], "int"))
  {
    vector<int> vec(dimension);
    read_vector(cin, vec, dimension);
    //...
  }
  else if (!strcmp(av[1], "double"))
  {
    vector<double> vec(dimension);
    read_vector(cin, vec, dimension);
    //...
  }
  // else if ...

  return 0;
}

Das laesst sich mit gcc-2.7.2 und libg++-2.7.1 compilieren. Leider
funktioniert 'string' nicht so wie es soll, sonst koennte man z.B.
'string(av[1]) == "int"' anstell von dem 'strcmp()' Kram schreiben.

Wenn man die verschiedenen Vektoren in dem selben Code verwendet werden
sollen, dann kann man sich eine abstrakte Basisklasse mit den noetigen
Eigenschaften definieren, von der man dann ein passendes Template
ableitet. Das kann man dann (typsicher) verwenden, ohne jemals wieder
einen 'switch' zu benoetigen.
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
Re: void* - Felder
#1428
Author: Claus Faerber
Date: Sun, 28 Jan 1996 10:12
54 lines
2073 bytes
Andrea Hermann <hermann@ipf.bau-verm.uni-karlsruhe.de> schrieb zu
void* - Felder
in Artikel <3109142F.41C67EA6@ipf.bau-verm.uni-karlsruhe.de> vom 26.01.96:
> Hi,
> ich habe hier ein Programmfragment, von dem ich nicht weiss,
> wieso es nicht tut:
>
> int main()
> {
>     void* feld;
>     int   typ;
>
>     // typ = 1 fuer int, 2 fuer double,...
>
>     switch( typ )
>     {
>         case 1: f = ( void* ) new int[n];
>                 for( int i = 0; i < n; i++ )
>                     ein >> (int)f[i];
                          // Du nimmst f[i], also das i-te Byte
                          // und konvertierst es nach int.

                          // Du muesstest also:

                             ((int*)f)[i]

                          // schreiben, dann wird der Zeiger zuerst
                          // nach int* konvertiert und dann der
                          // i-te int genommen

                          // Anmerkung: du solltest den Zeiger dann
                          // auch mit delete [] ((int*)feld)
                          // freigeben.

>                 break;
>
>         // andere Faelee
>      }
>      return 0;
> }
>
> Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
> Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
> wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...
>
> Andrea


Claus

------------------------------------------------------------------------
Claus Andre Faerber - claus@faerber.muc.de - http://www.muc.de/~cfaerber
Information at your fingertips - Wasserfeste Druckerfarbe an den Haneden
------------------------------------------------------------------------
Re: void* - Felder
#1442
Author: Karsten Baensch
Date: Mon, 29 Jan 1996 09:55
48 lines
1683 bytes
Andrea Hermann <hermann@ipf.bau-verm.uni-karlsruhe.de> writes:

>Hi, 
>ich habe hier ein Programmfragment, von dem ich nicht weiss,
>wieso es nicht tut:

>int main()
>{
>    void* feld;
>    int   typ;

>    // typ = 1 fuer int, 2 fuer double,...

>    switch( typ )
>    {
>        case 1: f = ( void* ) new int[n];
>                for( int i = 0; i < n; i++ )
>                    ein >> (int)f[i];
>                break;

>        // andere Faelee
>     }
>     return 0;
>}

>Prinzipiell soll das Teil n Werte aus einer Datei lesen, deren
>Typ in der Variablen typ verschluesselt ist und zur Laufzeit eingelesen
>wird. Aber irgendwie rafft er nicht, dass das jetzt ein int-Feld ist...

>Andrea

Wie soll ers auch 'raffen', wenn 'f' (bzw. 'feld' ?) doch vom Typ
'void*' ist? Also besser:

// ...
                for( int i = 0; i < n; i++ )
                    ein >> ((int*)f)[i];
                break;

// ...

Karsten

--
(  Email: Karsten.Baensch@hrz.tu-chemnitz.de                                ( 
 ) WWW:   http://www.tu-chemnitz.de/~kba/baensch.html                        )
(  Phone: (+49-) 0371/531-1252                                              ( 
 ) Mail:  Technical University, Computing Services, 09107 Chemnitz, Germany  )
Re: void* - Felder
#1445
Author: Watson
Date: Mon, 29 Jan 1996 10:17
28 lines
1386 bytes
Andrea Hermann wrote:
[...]
> int main()
> {
>     void* feld;
>     int   typ;
> 
>     // typ = 1 fuer int, 2 fuer double,...
> 
>     switch( typ )
>     {
>         case 1: f = ( void* ) new int[n];
>                 for( int i = 0; i < n; i++ )
>                     ein >> (int)f[i];
f[i] ist aequivalent zu *(f+i). 
*(f+i) bezeichnet die Adresse (char*)f+(i*sizeof(*f)).
Da aber der Ausdruck (*f) nicht gebildet werden kann
(dort ist ja nichts: void), ergibt dieser Ausdruck
einen Fehler. Die anderen haben ja schon auf das offen-
sichtliche hingewiesen (int *feld). Bleibt noch anzu-
merken, dass die Korrektur auch in der Expression erfolgen 
kann:

ein >> (int)(((int*)f)[i]);
-- 
*	Greetinx from Watson (sayegh@fokus.gmd.de)
	http://www.fokus.gmd.de/ovma/employees/sayegh/entry.html
	signal(SIGSEGV,SIG_IGN);
Re: void* - Felder
#1463
Author: Karsten Baensch
Date: Tue, 30 Jan 1996 15:07
12 lines
901 bytes
Watson <sayegh@fokus.gmd.de> writes:

>ein >> (int)(((int*)f)[i]);

'((int*)f)[i]'
ist schon vom Typ 'int'. Also wozu noch der letzte (int)(...)-Cast ?

--
(  Email: Karsten.Baensch@hrz.tu-chemnitz.de                                ( 
 ) WWW:   http://www.tu-chemnitz.de/~kba/baensch.html                        )
(  Phone: (+49-) 0371/531-1252                                              ( 
 ) Mail:  Technical University, Computing Services, 09107 Chemnitz, Germany  )
Re: void* - Felder
#1487
Author: Karl-Heinz Krause
Date: Wed, 31 Jan 1996 17:56
15 lines
1010 bytes
Am 30. Jan. 96 schrieb Karsten Baensch (kba@hrz.tu-chemnitz.de):

> Watson <sayegh@fokus.gmd.de> writes:

> >ein >> (int)(((int*)f)[i]);

> '((int*)f)[i]'
> ist schon vom Typ 'int'. Also wozu noch der letzte (int)(...)-Cast ?

Der zusätzliche (int)-Cast ist sogar falsch! Denn rechts vom
Eingabeoperator muß ein L-Wert stehen. Ein einfacher Typcast ergibt aber
einen R-Wert.


Karl-Heinz Krause
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads