"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿El comportamiento indefinido acecha en el encadenamiento std::string en el código de Bjarne Stroustrup?

¿El comportamiento indefinido acecha en el encadenamiento std::string en el código de Bjarne Stroustrup?

Publicado el 2024-11-11
Navegar:699

Does Undefined Behavior Lurk in std::string Chaining in Bjarne Stroustrup\'s Code?

¿La expresión de encadenamiento de std::string en el código de Bjarne Stroustrup exhibe un comportamiento indefinido?

En la cuarta edición de "El lenguaje de programación C" de Bjarne Stroustrup , un fragmento de código ejemplifica el encadenamiento usando el reemplazo de std::string método:

void f2() {
    std::string s = "but I have heard it works even if you don't believe in it";
    s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");

    assert(s == "I have heard it works only if you believe in it");
}

Este código, sin embargo, exhibe comportamiento no especificado en lugar de invocar un comportamiento indefinido.

La razón de este comportamiento no especificado radica en el orden de evaluación, que no está especificado para subexpresiones de llamadas a funciones encadenadas. En este caso, las llamadas a la función s.find se evalúan antes o después de la primera llamada a s.replace, lo que altera la longitud de la cadena resultante y afecta el resultado de la llamada de búsqueda posterior.

El ejemplo de la pregunta demuestra esto: cuando se evalúa por diferentes compiladores (clang, gcc), se obtienen resultados diferentes debido a diferentes evaluaciones pedidos.

Detalles

Los argumentos de función tienen un orden de evaluación no especificado y, aunque el encadenamiento de llamadas a función introduce un orden de evaluación de izquierda a derecha para cada invocación de función, los argumentos de cada llamada se secuencian solo antes de con respecto a esa llamada de función en particular.

En el ejemplo, esta indeterminación surge en la evaluación de s.find("even") y s.find(" don't") con respecto a s.replace(0, 4, "").

Ignorando más desgloses de subexpresiones, la secuencia de Los pasos de evaluación y su interdependencia se pueden representar de la siguiente manera:

Step 1: s.replace(0, 4, "")  // A
Step 2: s.find("even")       // B
Step 3: s.replace(B, 4, "only") // C
Step 4: s.find("don't")      // D
Step 5: s.replace(D, 6, "")   // E

Si bien A se secuencia antes que B, que a su vez se secuencia antes de C, no existe ninguna relación de secuenciación entre B y D con respecto a A. Como resultado, D puede evaluarse antes o después de A, lo que lleva a diferentes resultados según la secuencia elegida.

C 17 Cambios

El estándar C 17 fortalece el orden de las reglas de evaluación para expresiones postfix y su lista de expresiones, dando al código en cuestión un comportamiento bien especificado. La secuenciación es la siguiente:

  • La expresión postfijo se secuencia antes de cada expresión en la lista de expresiones.
  • La inicialización de cada parámetro se secuencia indeterminadamente con respecto a la de cualquier otro parámetro.

Por lo tanto, en C 17 y posteriores, este código siempre se evaluará correctamente.

Declaración de liberación Este artículo se reimprime en: 1729674849 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3