c standard vs. compiler extensions



  • Hallo,

    ich moechte gerne verstehen, was der unterschied zwischen 2 programmen ist. version 1 verhaelt sich konform zum standard, version 2 verwendet gcc compiler extensions...

    version 1:

    #include <stdio.h> 
    #include <stdlib.h>
    
    typedef struct foo foo;
    typedef struct buffer buffer;
    
    struct buffer {
    	int rows;
    	int cols;
    	float *data;
    };
    
    buffer buffer_new(int rows, int cols) {
    	buffer b;
    	b.rows = rows;
    	b.cols = cols;
    	b.data = (float*)malloc(rows*cols);
        return b;
    }
    
    void buffer_free(buffer *b) {
    	free(b->data);	
    }
    
    float buffer_read(buffer *b, int i, int j) { 
        return *((b->data + i * b->cols) + j); 
    } 
    
    void buffer_write(buffer *b, int i, int j, const float val) { 
        *((b->data + i * b->cols) + j) = val; 
    } 
    
    struct foo { 
        buffer *buffer_ptr;
    };
    
    foo foo_new(buffer *buffer_ptr_) { 
        foo f; 
        f.buffer_ptr = buffer_ptr_;
        return f; 
    }
    
    float foo_read(foo *f, int row, int col) {
    	return buffer_read(f->buffer_ptr, row, col);
    }  
    
    int main() 
    { 
    	buffer b = buffer_new(2, 5000);
    
        int i = 0; 
        for (i = 0; i < 100; i++) { 
            buffer_write(&b, 1, i, i);
        } 
    
        foo f = foo_new(&b);
    
        for (i = 0; i < 100; i++) { 
            printf("%f\n", foo_read(&f, 1, i));
        }
    
        buffer_free(&b);
    
        return 0; 
    }
    

    version 2:

    #include <stdio.h> 
    #include <stdlib.h>
    
    typedef struct foo foo;
    typedef struct buffer buffer;
    
    struct buffer {
    	int rows;
    	int cols;
    	float data[];
    };
    
    buffer *buffer_new(int rows, int cols) {
    	buffer *b = (buffer*)malloc(sizeof(buffer) + rows*cols);
    	b->rows = rows;
    	b->cols = cols;
        return b;
    }
    
    void buffer_free(buffer *b) {
    	free(b);	
    }
    
    float buffer_read(buffer *b, int i, int j) { 
        return *((b->data + i * b->cols) + j); 
    } 
    
    void buffer_write(buffer *b, int i, int j, const float val) { 
        *((b->data + i * b->cols) + j) = val; 
    } 
    
    struct foo { 
        buffer *buffer_ptr;
    };
    
    foo foo_new(buffer *buffer_ptr_) { 
        foo f; 
        f.buffer_ptr = buffer_ptr_;
        return f; 
    }
    
    float foo_read(foo *f, int row, int col) {
    	return buffer_read(f->buffer_ptr, row, col);
    }  
    
    int main() 
    { 
    	buffer *b = buffer_new(2, 5000);
    
        int i = 0; 
        for (i = 0; i < 100; i++) { 
            buffer_write(b, 1, i, i);
        } 
    
        foo f = foo_new(b);
    
        for (i = 0; i < 100; i++) { 
            printf("%f\n", foo_read(&f, 1, i));
        }
    
        buffer_free(b);
    
        return 0; 
    }
    


  • Bei der ersten Version sind struct und Daten getrennt im Speicher.
    data zeigt auf die Daten.

    Bei der zweiten Version ist es ein gemeinsamer Block.
    Die Daten sind ein Teil der struct . Aber auch nicht so richtig - kann man am sizeof() erkennen.

    Es wird ausgenutzt, dass da Arrays auch die Länge 0 (Null) haben können. Der Standard läßt das nicht zu.



  • Zeile 14 ist Nonsens, du schnappst irgendwo was auf und weißt nicht, damit umzugehen.
    flexible array member (FAM) sind C99 Standard, und den Deppen-malloc-Cast benutzt du immer noch.

    buffer *b = malloc(sizeof*b + sizeof(float[rows*cols]));
    


  • danke fuer den hinweis....was ist sizeof*b ?


  • Mod

    thomasrust schrieb:

    danke fuer den hinweis....was ist sizeof*b ?

    Das gleiche wie sizeof(*b)


Anmelden zum Antworten