2011-01-13 16 views
6

He estado estudiando el código fuente GNU Scientific Library y sigo viendo el siguiente tipo de declaraciones:C99 const pasar por valor

double cblas_ddot (const int N, const double * x, const int incx, const double * y, const int incy) 

En C99, ¿hay alguna (optimizational) en beneficio de declarar un argumento que se pasa por valor (por ejemplo, N o incy en el ejemplo anterior) const? De todos modos, hay una copia de ellos porque se pasan por valor, ¿no es así?

Thx! Kornel

Respuesta

11

Probablemente no haya beneficio para la persona que llama, sino para el destinatario. Declarar un parámetro de función const tiene el mismo impacto beneficioso que declarar otras variables locales const al imponerse un error sobre usted (como el programador de la función) cada vez que intente modificar esto.

En implementaciones no tan inteligentes, tal declaración probablemente también podría tener un impacto en la decisión si una función está en línea. Pero supongo que hoy en día los compiladores tomarán tal decisión sobre lo que deducen directamente de la definición de la función.

Sin duda se puede ver como una restricción del lenguaje que esta especificación de la implementación se expresa en su interfaz.

3

Sí. La opción "const" se usa generalmente para indicar que lo que se pase a esta función no se verá alterado. En compilación, no hay diferencia. Todavía se pasa por valor.

3

Como han indicado otros, las funciones se declaran de esta manera para que, dentro del alcance de la función, esa variable no sea modificable y al hacerlo, su compilador debería advertirle.

En cuanto a por qué es posible que desee hacer esto, considere qué le permite hacer un puntero, es decir, puede desreferenciar el puntero que ha pasado y editar los valores de los datos a los que apunta. Usar const es una buena manera de evitar editar accidentalmente el valor de algo que la persona que llama piensa que no ha cambiado.

Por ejemplo, considere esto:

#include <stdio.h> 

void add(int* result, const int* x, int* y) 
{ 
    *result = *x + *y; 
    (*y)++; /* <-- the caller won't expect this! */ 

} 

int main(int argc, char** argv) 
{ 
    int a = 7; 
    int b = 10; 
    int c = 0; 

    add(&c, &a, &b); 

    printf("%d + %d = %d\n", a, b, c); 
    return 0; 
} 

Este escupe 7+11=17. Ahora bien, este es un caso trivial, no graves, pero todo tipo de cosas puede suceder si tuviéramos que confiará en nada importante ...

Si usted se pega const contra la variable, debe obtener:

constexample.c: In function ‘add’: constexample.c:7:5: error: increment of read-only location ‘*y’

Editar, para mayor aclaración:

una buena razón para declarar un tipo const para una variable puntero no es una variable que representa el tamaño de algo, o cualquier variable que contiene el valor máximo de una matriz. Consideremos:

int editstring(char* result, ..., const char* source, const size_t source_len); 

Ahora, usted dice a sí mismo, pero nunca había editar source_len. Bueno, digamos en tu algoritmo que haces por cualquier razón. Si su cambio aumenta el valor de source_len, corre el riesgo de acceder a la memoria más allá de lo que ha asignado. Configurando const generará un error de compilación si intenta modificar ese valor.

Debo señalar, en doble línea de subrayado, que const es solo una forma de decirle al compilador "Prometo no editar esto". No garantiza que la memoria sea de solo lectura, pero es una forma de marcar su intención de forma que se atrapen errores. Si no necesita modificarlo, declare const.

Y como usted solicitó, el conjunto generado por las dos versiones es idéntico.

+2

En su ejemplo, no declara los parámetros 'const' sino los datos a los que apunta el parámetro. Para los indicadores, lo que el OP solicitó sería algo así como 'int * const result'. Además, si mal no recuerdo, '* y ++' primero incrementa el puntero y luego lo desreferencia. Nada que pueda molestar a la persona que llama sucede, ¿no? –

+0

Tienes razón, mi error, debería haber sido '(* y) ++;' Sin embargo, nunca dije que declarar mis parámetros const afecta al puntero; de hecho, el * punto * de mi ejemplo es que altera el memoria fuente Sin embargo, he agregado una sección extra sobre la utilidad de las constelaciones de variables estándar. –

Cuestiones relacionadas