Quali potrebbero essere i vantaggi e gli svantaggi del decadimento degli array Nd rispetto ai puntatori a livello N?

2

Ho pensato ad un paio di possibili estensioni del linguaggio C che mi piacerebbe conoscere l'opinione degli altri su. 1 Questo riguarda gli array multidimensionali.

Immagina la seguente situazione in C:

void matrix_mul(double **res, double **a, double **b, size_t n, size_t m, size_t r);

Non puoi passare una double mat[4][4] (per esempio) a questa funzione. Se si definisce la funzione come:

void matrix_mul_N_M_R(double res[N][R], double a[N][M], double b[M][R]);

Stai solo perdendo un algoritmo fine perfettamente scritto su una certa dimensione di matrici.

Ciò che è venuto a me (nella doccia ovviamente), era il decadimento di array multidimensionali a puntatori multi-livello. Questa è un'estensione al decadimento degli array 1d ai puntatori.

Semanticamente, questo consentirebbe al primo tipo di funzione di funzionare su qualsiasi array bidimensionale. Tecnicamente, questo è il modo in cui sarebbe implementato. Il seguente codice:

double a[3][5];
double b[5][4];
double c[3][4];
...
matrix_mul(c, a, b, 3, 5, 4);

sarebbe equivalente a:

double a[3][5];
double b[5][4];
double c[3][4];
...
double **__a_decay = {a[0], a[1], a[2]};               /* generated by compiler */
double **__b_decay = {b[0], b[1], b[2], b[3], b[4]};   /* generated by compiler */
double **__c_decay = {c[0], c[1], c[2]};               /* generated by compiler */
matrix_mul(__c_decay, __a_decay, __b_decay, 3, 5, 4);  /* first three arguments decayed */

L'applicazione per tale estensione è molto limitata? Ci sono insidie? Questo potrebbe portare a codice non sicuro dove non usare questa funzione non lo farebbe? In quale altro posto potrebbe essere utile una funzione del genere?

1 Nota che non ho intenzione di creare un'altra lingua da solo, ma vorrei essere sicuro dei vantaggi e delle insidie della funzione prima di provare a suggerirli al C Standard Committee.

    
posta Shahbaz 16.09.2013 - 01:03
fonte

3 risposte

1

In che modo l'estensione proposta gestirà la situazione in cui un array multidimensionale non viene assegnato staticamente? Avere l'estensione limitata ai casi in cui l'allocazione è statica renderebbe il suo comportamento incoerente con un'altra gestione dell'array, ma se l'estensione non è limitata alle allocazioni di array statici, passare un double[5000][5000] a una funzione che si aspetta un double** richiedere al compilatore di generare e compilare completamente un (double*)[5000] , anche se la funzione non ne userebbe la maggior parte (o anche nessuna) dei suoi elementi ogni volta che viene chiamata la funzione.

Un'estensione più utile potrebbe essere quella di aggiungere tipi come double[][] e double[][][] come tipi nella lingua, e ognuno di questi tipi con N dimensioni essere memorizzato come double* insieme a valori N-1 di tipo tipo %codice%. Sarebbe necessario disporre di metodi separati per array frastagliati e lineari, ma non sarebbe necessario disporre di metodi diversi per ciascuna dimensione di array lineare.

    
risposta data 07.11.2014 - 15:48
fonte
5

Forse hai già ascoltato la famosa citazione di Antoine de Saint-Exupery:

A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.

Quindi, prima di pensare alle estensioni della lingua, dovresti pensare a risolvere un problema con le funzionalità linguistiche esistenti in un modo conveniente (e suppongo che questo sia quello che il comitato standard C ti risponderà se davvero fai una proposta del genere).

In C, la soluzione naturale a questo tipo di problema è definire un

struct Matrix
{
    int sizeX;
    int sizeY;
    double *values; /* vector with sizeX * sizeY elements */
};

(o qualcosa di simile) e creare operazioni che funzionano su quel tipo di dati, incluse le operazioni per l'allocazione e la liberazione della memoria, le operazioni per riempire quel tipo di struttura con i valori di un array 2D ecc.

    
risposta data 16.09.2013 - 08:29
fonte
4

Il problema più grande di questo mi sembra essere il fatto che sta prendendo il concetto C degli array che si decompongono ai puntatori e si costruiscono su di esso.

Gli array che decadono ai puntatori sono già problematici in termini di chiarezza. Se vedi una funzione che accetta un parametro di tipo int* , vuol dire che si aspetta un array di numeri interi, o un singolo intero come un argomento "falso passato per riferimento"? Non c'è modo di saperlo senza esaminare il codice della funzione - o la documentazione, supponendo che esista e sia aggiornata e accurata.

Se poi lo espandi a più livelli di decadimento dell'array, la complessità e l'incertezza crescono esponenzialmente con ogni dimensione ...

    
risposta data 16.09.2013 - 01:29
fonte

Leggi altre domande sui tag