2009-10-22 12 views
21

Decir que tengo este ejemplo:¿Por qué un calificador de tipo en un tipo de retorno no tiene sentido?

char const * const 
foo(){ 
    /* which is initialized to const char * const */ 
    return str; 
} 

Cuál es la forma correcta de hacerlo para evitar la advertencia del compilador "calificador de tipo de tipo de retorno no tiene sentido"?

+5

¿Es solo yo o esta pregunta le falta claridad? – jldupont

+2

@ Jean-Lou: Estoy de acuerdo en que el cuerpo de la pregunta en sí es algo vago, pero el título de la pregunta realmente expresa su significado. – sbi

Respuesta

22

La forma en que lo escribió, decía "el valor del puntero devuelto es const". Pero los valores de tipo no de clase no son modificables (heredados de C), y por lo tanto el Estándar dice que los valores de tipo no de clase nunca son calificados (la const de extremo derecho fue ignorada incluso si usted lo especificó) ya que const sería algo redundante . No se escribe él - ejemplo:

int f(); 
    int main() { f() = 0; } // error anyway! 

    // const redundant. returned expression still has type "int", even though the 
    // function-type of g remains "int const()" (potential confusion!) 
    int const g(); 

Tenga en cuenta que para el tipo de "g", la const es significativa, pero para las expresiones generadas a partir de rvalue tipo int const se ignora la const. Por lo que el siguiente es un error:

int const f(); 
    int f() { } // different return type but same parameters 

No hay manera conocida para mí se podía observar el "const" excepción de conseguir en el tipo de "g" en sí (y pasando &f a una plantilla y deducir su tipo , por ejemplo). Finalmente observe que "char const" y "const char" significan el mismo tipo. Te recomiendo que te conformes con una noción y la uses en todo el código.

+7

Recomiendo usar siempre "const" (char const * const), ya que es la única forma en que puede usar "const" * consistentemente *. Sin embargo, estoy en desventaja en esto ... – DevSolar

+0

@DevSolar: La mayoría de los gurús (Sutter, por ejemplo) parece estar de acuerdo contigo y coloca los calificadores DESPUÉS del tipo (clase const &, clase volátil). –

+1

@DevSolar, solo para aclarar: no están de acuerdo contigo sobre la última const final. Pueden estar de acuerdo con tu primer const que aparece después del nombre del tipo. –

4

En C, porque los valores de retorno de función y los valores de calificación no tienen sentido.
Puede ser diferente en C++, ver otras respuestas.

const int i = (const int)42; /* meaningless, the 42 is never gonna change */ 
int const foo(void); /* meaningless, the value returned from foo is never gonna change */ 

Solo los objetos pueden ser calificados significativamente.

const int *ip = (const int *)&errno; /* ok, `ip` points to an object qualified with `const` */ 
const char *foo(void); /* ok, `foo()` returns a pointer to a qualified object */ 
+0

Tenga en cuenta que para los tipos de clase, el 'const' para los valores devueltos no tiene sentido, ya que se le permite llamar a funciones miembro modificadoras en valores no constantes. (Acabamos de tener esto aquí con cadenas el otro día: '(s1 + s2) .append (s3)'.) Como de costumbre, la respuesta de litb explica todo esto en detalle y corrección. – sbi

+0

Quise decir mi respuesta para tratar con C solamente. Actualizado para reflejar eso. – pmg

+0

Ah, le hicieron una pregunta "C/C++". (Lenguaje extraño, eso.) Lo siento, no había visto esto tampoco. – sbi

1

Ninguna de las respuestas anteriores en realidad responde al "camino correcto para hacerlo" parte de la pregunta.

yo creo que la respuesta a esto es:

char const * foo(){ 

que dice va a devolver un puntero a un personaje constante.

+0

Entiendo que esto es un puntero constante a un carácter, no un puntero a un carácter constante – atlex2

+0

No, en realidad @ user1076543 es correcto, es un puntero a un carácter constante como 'char const *' y 'const char *' mismo. Un puntero constante para un personaje sería 'char * const'. –

Cuestiones relacionadas