¿Cuándo necesita una cadena terminada en nulo en un escenario de solo lectura?

10

He estado jugando con la std::string_viewbiblioteca y he estado pensando en cambiar una base de código en la que he estado trabajando para usar std::string_viewtanto como sea posible. Sin embargo, en muchos de los hilos que he leído sobre el tema de cuándo y dónde usar en std::string_viewlugar de const std::string &. He visto muchas respuestas que dicen: "Cuando no necesita una cadena terminada en nulo". Entonces, cuando comencé a buscar en la web, "¿cuándo necesita una cadena terminada en nulo?" Realmente no he encontrado ninguna respuesta útil sobre el tema.

Se me ocurre un ejemplo de una biblioteca externa a la que vinculará que requiere a std::string. Y en ese caso, necesitaría una cadena terminada en nulo ya que esa biblioteca lo requiere. Supongo que otro ejemplo sería si necesita modificar la cadena en sí, pero luego no la pasaríamos const &si necesitáramos modificarla.

Entonces, ¿cuándo necesitaría usar una cadena terminada en nulo?

Enlaces que he mirado:

  1. ¿Cómo es exactamente std :: string_view más rápido que const std :: string &?
  2. ¿Cuándo pasaría const & std :: string en lugar de std :: string_view?
  3. ¿Por qué solo ver cadena?
  4. ¿Tiene sentido usar const std :: string & argumentos en C ++ 17?
Sailanarmo
fuente
55
Para interactuar con las API de C, principalmente.
nuez
@uneven_mark, ¿puede proporcionar un ejemplo de uno?
Sailanarmo
La respuesta aceptada a la cuarta pregunta que vincula parece que responde a esta pregunta.
François Andrieux el
1
@Sailanarmo La mayoría de las funciones de, por ejemplo, POSIX o cualquier otra biblioteca de C toman un const char*argumento. La respuesta de eerorika tiene un ejemplo.
nuez
1
@ FrançoisAndrieux, así que realmente la respuesta es: "¿Mientras la API no requiera una cadena terminada en nulo?"
Sailanarmo

Respuestas:

10

¿Cuándo necesita una cadena terminada en nulo?

Necesita una cadena terminada nula cada vez que la API que utiliza dice que la necesita. Este requisito es omnipresente en las interfaces C y no se establece explícitamente en alguna documentación. Si un argumento de función es un char*(posiblemente const), y no hay un argumento de longitud, debe asumir el requisito a menos que la documentación indique lo contrario.

Tomemos la función execve(del estándar POSIX) como ejemplo:

int execve(const char *pathname, char *const argv[], char *const envp[]);

Si pasa un argumento terminado no nulo como pathname, entonces el comportamiento de su programa será indefinido.

eerorika
fuente
Entonces, en este caso, el nombre de ruta, si fuera un std::string, ¿se ejecutaría como execve(pathname.c_str(),...,...)?
Sailanarmo
6

En realidad es bastante fácil de saber. Si está llamando a una función que solo toma una cadena c ( char*/ const char*), entonces necesita una cadena terminada en nulo, ya que esa es la única manera de saber dónde está el final de la cadena.

Si, en cambio, tiene una función que toma un char*/ const char*más el tamaño, o solo dos punteros que marcan el comienzo y el final de los datos, entonces no necesita una cadena terminada en nulo ya que tiene / puede obtener el tamaño de la cadena sin iterar a un terminador nulo.

NathanOliver
fuente