libreria declarar c++ static constant-expression

libreria - declarar string en c++



¿Por qué crear una cadena estática const std:: string puede ser una excepción? (3)

Tengo constantes de cadena, para las cadenas que uso en varios lugares en mi aplicación:

namespace Common{ static const std::string mystring = "IamAwesum"; }

Al publicar una pregunta sobre otra cosa ( ¿Qué sucede con un archivo .h que no está incluido en un objetivo durante la compilación? ), Otro usuario realizó el siguiente comentario:

Tenga en cuenta que su cadena estática es global en este caso. Por lo tanto, podrían crear una excepción en cualquier momento y no se pueden capturar. Te aconsejo que uses la función que devuelve una referencia de tu cadena. std :: string const & mystring {static std :: string const mystring = "IamAwesum"; devuelve mystring} de esta manera su objeto solo se construirá cuando sea necesario

¿Alguien puede explicar por qué usar constantes estáticas de la manera en que lo hago arriba, corre el riesgo de lanzar excepciones?


N4140 § 3.6.2 [basic.start.init] / 4

Se define por la implementación si la inicialización dinámica de una variable no local con duración de almacenamiento estática se realiza antes de la primera declaración de main .

Al aire libre

N4140 § N4140 15.3 [except.handle] / 13

Las excepciones lanzadas en destructores de objetos con duración de almacenamiento estático o en constructores de objetos de ámbito de espacio de nombres con duración de almacenamiento estática no son detectadas por una función-try-block en main() .

Simplemente no puede capturar una excepción generada por el constructor de la cadena, por ejemplo, std::bad_alloc .

(opinión) Dicho esto, para estas pequeñas cuerdas me parece que este tipo de consideración es paranoica.


El único "problema" (si puede llamarlo así) que veo con su código es que está desperdiciando al copiar innecesariamente datos que ya son constantes en un búfer asignado dinámicamente (que es formalmente constante, pero no en realidad ). Esto utiliza el doble de memoria física que la necesaria y hace una copia innecesaria.

¿Importa? Casi seguro que no. Incluso en un sistema de "memoria bastante limitada", esto casi no se notará hoy en día, ni desde el punto de vista del tiempo de ejecución, ni por su consumo de memoria.

En cuanto a las excepciones, por supuesto, es técnicamente cierto que la asignación que std::string debe realizar puede fallar, y por lo tanto, el constructor podría lanzar, y usted no podría atraparla. Pero por favor sea realista.
Es casi seguro que esto no suceda, pero incluso si lo hace ... si algo tan trivial como asignar memoria a un par de cadenas falla mientras se inicia su programa, ¡tiene un problema muy serio en una escala completamente diferente!
Además, como se señaló en un comentario en otra respuesta anterior: suponiendo que esto suceda, ¿qué vas a hacer al respecto? El programa es totalmente incapaz de ejecutarse, por lo que no hay mucho menos que matar el programa que posiblemente podrías hacer.

Ahora, ya que C ++ 17 no está muy lejos y string_view ya está disponible en std::experimental en varios compiladores convencionales, hay otra cosa que puedes probar: usar lo correcto .

Una string_view , al contrario de una string , no asignará memoria no constante, copiará datos constantes en eso y luego fingirá que es constante. En su lugar, administrará un puntero directamente a los datos constantes, y eso es todo.
De esa manera, sus constantes son realmente constantes (no solo formalmente), no hay asignaciones, no hay posibilidad de excepciones y no hay doble uso de memoria. Y en su mayor parte, todavía parece y huele como una string . Las únicas diferencias notables son que string_view no garantiza la terminación string_view (pero la constante de caracteres a la que apunta lo hace, por lo que es irrelevante), y el hecho de que es realmente constante, no modificable ... que es exactamente lo que desea .


El documento pdf se refiere principalmente a excepciones del objeto ctor y al orden de inicialización fiasco con bibliotecas estáticas o enlazadas dinámicamente.

El único peligro que veo en su código para las excepciones es si el ctor de std :: string se lanzará cuando se llame.

Si realmente quieres estar seguro, puedes usar static const char * mystring que no llamará a un ctor de C ++.

También está la cuestión de que el código esté en una biblioteca compartida que luego debe colocarse en el espacio de direcciones del proceso. No veo eso como un problema importante si no usas ctors complicados (ctors que pueden lanzar).