Fundamentalmente, sí, es seguro en el sentido de que el valor durará indefinidamente porque es estático.
No es seguro en el sentido de que ha devuelto un puntero constante a datos variables, en lugar de un puntero variable a datos constantes. Es mejor si las funciones de llamada no se les permite modificar los datos:
const char *GetString(void)
{
static char sTest[5];
strncpy(sTest, "Test", sizeof(sTest)-1);
sTest[sizeof(sTest)-1] = '\0';
return sTest;
}
En el caso sencillo se muestra, no es necesario preocuparse por los desbordamientos de búfer, aunque mi versión del código no se preocupe, y asegura nula terminación. Una alternativa sería utilizar la función TR24731strcpy_s
lugar:
const char *GetString(void)
{
static char sTest[5];
strcpy_s(sTest, sizeof(sTest), "Test");
return sTest;
}
Más importante aún, las dos variantes devolver un puntero (variable) para los datos constantes, por lo que el usuario no debe ir modificando la cadena y (probablemente) pisoteo fuera del rango de la matriz. (Como señala @strager en los comentarios, devolver un const char *
no garantiza que el usuario no intente modificar los datos devueltos. Sin embargo, tienen que convertir el puntero devuelto para que no sea const y luego modificar los datos ; esto invoca un comportamiento indefinido y todo es posible en ese punto.)
Una ventaja del retorno literal es que la promesa de no escritura generalmente puede ser aplicada por el compilador y el sistema operativo. La cadena se colocará en el segmento de texto (código) del programa, y el sistema operativo generará un error (violación de la segmentación en Unix) si el usuario intenta modificar los datos apuntados por el valor de retorno.
[Al menos una de las otras respuestas indica que el código no es reentrante; eso es correcto. La versión que devuelve el literal es reingresante. Si re-entrada es importante, la interfaz necesita ser arreglado de manera que la persona que llama proporciona el espacio donde se almacenan los datos]
"En general, se debe evitar" podría ser demasiado fuerte, pero lo cierto es que debe ser consciente de los riesgos y limitaciones. +1 para mayor claridad en _why_ está bien. – dmckee
Estoy de acuerdo con dmckee, los problemas de reentrada se deben al diseño de la estática que está activa en las llamadas a funciones. no es un mal comportamiento pero deberías ser consciente del riesgo, de hecho. –