2010-03-03 48 views
8

Tengo algunas preguntas acerca de los valores predeterminados en función de una lista de parámetrosuna pregunta sobre el valor por defecto en C++

1) es el valor predeterminado de una parte de la firma? ¿Qué pasa con el tipo de parámetro de los parámetros predeterminados?

2) ¿Dónde se almacena el valor predeterminado? ¿En la pila o en el montón global o en el segmento de datos constantes?

Gracias!

+1

El argumento predeterminado es algo que existe solo para el compilador. Si omite un parámetro en una llamada a función, el compilador escribirá el código de manera que se pase silenciosamente * como si lo hubiera especificado en la llamada *. Una vez compilado, su programa no tiene ningún concepto real de valores predeterminados, por lo tanto, no están realmente 'almacenados' en ninguna parte. –

Respuesta

15

No, el valor predeterminado argumento no es parte de la firma y no es parte del tipo de función.

El tipo de parámetro es una parte de la firma. Pero el tipo de argumento predeterminado no tiene ningún efecto de tipo de parámetro, es decir, el tipo de argumento predeterminado no tiene efecto en la firma.

Los argumentos predeterminados no se "almacenan" en ningún lugar específicamente. Los argumentos predeterminados son "azúcar sintáctico" que existe (como argumentos predeterminados) solo durante la compilación del programa. Si durante el compilador de compilación se da cuenta de que falta algún argumento, usará el argumento predeterminado, tal como lo haya especificado usted. La evaluación del argumento predeterminado se realiza en el contexto de la persona que llama. Si especifica un objeto temporal como argumento predeterminado, se creará un elemento temporal por separado cada vez que llame a la función utilizando el argumento predeterminado y se destruirá inmediatamente después de que finalice la expresión de llamada.

void foo(T t = T()); 
// A new temporary will be used as an argument every time you call it as `foo()` 

foo(); 
// Equivalent to `foo(T())`. A temporary is created here, passed as an argument and 
// destroyed afterwards, just like an explicit temporary would be 

Si especifica un objeto existente con una duración de almacenamiento estático como un argumento predeterminado, entonces se almacenarán siempre que lo definen.

T global; 

void foo(T& t = global); 
// In this case you are using a global object as a default argument 
// It is you who "store" it wherever you want to store it 

foo(); 
// Equivalent to `foo(global)` 

Si se declara argumentos por defecto, pero en realidad nunca se utilicen, es decir, si especifica los argumentos de forma explícita cada vez, entonces el programa compilado tendrá ningún rastro de estos argumentos de ningún tipo (por eso los llamé en tiempo de compilación "azúcar sintáctica").

P.S.Para incluir lo que dice Johannes en el comentario siguiente: aunque el argumento predeterminado (cuando se usa) se evalúa en el contexto de la persona que llama en el momento de la llamada, no se hace por "sustitución textual" como podría aparecer en mis ejemplos encima. En particular, la búsqueda de nombre para los nombres utilizados en los argumentos predeterminados se realiza en el punto en que el argumento predeterminado se especifica en la declaración de la función, no en el punto de la evaluación en la persona que llama.

+1

Hechos interesantes: los nombres se buscan en el momento de la especificación del argumento por defecto. Esto puede hacer diferencias: 'void f (string s = string (" foo ")); int main() {int cadena; F();/* valid */f (cadena ("foo"));/* error * /} '. Otra cosa interesante es que cada ámbito tiene su propio conjunto de argumentos predeterminados: 'void f (int = 10); int main() {void f (int = 20); F();/* llamado con 20 * /} '. Otro caso interesante: 'string s =" foo "; void f (int s, string f = s); 'falla porque' s' está ligado al primer parámetro en su lugar. –

+0

Además, no solo los argumentos predeterminados son específicos del alcance, también se pueden agregar "incrementalmente" de declaración a declaración (pero no redefinidos), como en 'void foo (int a, int b); void foo (int a, int b = 2); void foo (int a = 3, int b); '. Entre estas declaraciones, la función tiene diferentes números de argumentos predeterminados. – AnT

0
// declaration 
void func(int param = 3); 

//... 

int main(void) 
{ 
    // doing 
    func(); 

    // will probably give the same assembly as doing 
    func(3); 
} 

Así que simplemente presionará 3 como cualquier otro parámetro antes de llamar a func.

tenga en cuenta que esto es sólo una suposición.

1

1) ¿El valor predeterminado es parte de la firma?

¿Qué pasa con el tipo de parámetro de los parámetros por defecto?

El tipo siempre está en la firma (si no lo hace en extern "...") independientemente de que tenga valores predeterminados o no.

2) ¿Dónde se almacena el valor predeterminado?

En ninguna parte. El compilador los completa automáticamente.

1

1) El tipo/firma de una función que tiene parámetros por defecto es el mismo que el tipo/firma de la función de si el parámetro era allí sin ningún valor por defecto:

// foo1 and foo2 are both functions taking an int, and returning an int. 
int foo1(int); 
int foo2(int a = 0); 

typedef int(*int_fn_ptr)(int); 
int_fn_ptr f1 = foo1; // OK, assigning a function pointer 
int_fn_ptr f2 = foo2; // OK 

typedef int(*void_fn_ptr)(void); 
void_fn_ptr f3 = foo2; // doesn't compile 

2) Los valores por defecto son creado por la persona que llama cuando se llama a la función. En efecto, el compilador simplemente sustituye:

foo2(); 

con:

foo2(0); 

tan pronto como se lo ve. Esta es la razón por la que los valores predeterminados deben especificarse en el lugar donde la función es declarada, donde los llamantes pueden verlos.

En algunos otros idiomas, el valor predeterminado "pertenece" a la función en sí. Podría tener sentido preguntar dónde se "almacena" ese valor predeterminado, pero este no es el caso en C++.