void **mar_init(...), float **f; --> WTF



  • net schrieb:

    jo, aber es reicht ein einfacher void*, weil der schon eine adresse beinhaltet, die auf alles mögliche zeigen kann. auch auf andere pointer oder pointer auf pointer usw. bei void* ist mehrfache indirektion echt überflüssig

    Das fuehrt dazu, dass auf beiden Seiten (beim Caller und bei der API-Funktion) dann bloedsinnige Casts erforderlich sind:

    void apifunc( void* arg ) {
       *((void**)arg) = allocate_it();
    }
    void caller( void ) {
       void* ptr = 0;
       apifunc( (void*)(&ptr) );
    }
    

    waehrenddessen "void**" viel sauberer und leicher verstaendlich ist:

    void apifunc( void** arg ) {
       *arg = allocate_it();
    }
    void caller( void ) {
       void* ptr = 0;
       apifunc( &ptr );
    }
    

    klaro? 🙂



  • Power Off schrieb:

    net schrieb:

    jo, aber es reicht ein einfacher void*, weil der schon eine adresse beinhaltet, die auf alles mögliche zeigen kann. auch auf andere pointer oder pointer auf pointer usw. bei void* ist mehrfache indirektion echt überflüssig

    Das fuehrt dazu, dass auf beiden Seiten (beim Caller und bei der API-Funktion) dann bloedsinnige Casts erforderlich sind:

    na, so schlimm ist das nicht. bei void* kommt man in den meisten fällen sowieso nicht um casts herum, wenn man was damit machen will. und wenn einem das zu kryptisch erscheint kann man ja noch ein 'typedef' oder '#define' daraus machen.

    btw: in c braucht der caller keinen cast zu machen, in c++ aber schon.



  • masterofx32 schrieb:

    void** als Parameter ist ja verständlich, aber was bringt einem denn ein Doppel-Voidpointer als Rückgabewert?

    Es zeigt, dass ein zweidimensionales, obskures Array zurueckgegeben wird, d.h. der Aufrufer weiss, das es zweidimensional ist, weiss aber nicht, welche Daten darin enthalten sind. Vielleicht sind die Datentypen ja auch variabel, dann ergibt es auch einen Sinn.

    void** alloc_float_or_double_array( size_t xdim, size_t ydim, int type ) {
       if ( type == 1 ) {  // float-Array
          float** f = (float**) malloc( sizeof(float*) * ydim ); size_t i;
          if ( f == 0 ) return 0;
          for ( i=0; i < ydim; ++i ) {
             f[i] = (float*) malloc( sizeof(float) * xdim );
             if ( f[i] == 0 ) { 
                while ( --i >= 0 ) free( f[i] );
                free( (void*) f );
                return 0;
            }
          }
          return (void**) f;
       }
       if ( type == 2 ) {  // double-Array
          double** d = (double**) malloc( sizeof(double*) * ydim ); size_t i;
          if ( d == 0 ) return 0;
          for ( i=0; i < ydim; ++i ) {
             d[i] = (double*) malloc( sizeof(double) * xdim );
             if ( d[i] == 0 ) { 
                while ( --i >= 0 ) free( d[i] );
                free( (void*) d );
                return 0;
            }
          }
          return (void**) d;
       }
       return 0;     
    }
    void testfunc( void ) {
       float** f = (float**) alloc_float_or_double_array( 30U, 40U, 1 );
       if ( f != 0 ) { /* ... */ }
    }
    


  • net schrieb:

    btw: in c braucht der caller keinen cast zu machen, in c++ aber schon.

    Laut Standard mag das stimmen -- und zwar auch nur, wenn der Level of Indirection derselbe ist -- aber die Compiler verlangen in der Praxis oft immer noch casts.


Anmelden zum Antworten