El otro día hubo una reunión del Comité para la Estandarización del lenguaje de programación C ++ en Belfast. Alrededor de 400 comentarios sobre C ++ 20 llegaron desde los representantes de los países al comité, y la mitad de ellos logró abordarlo.
Debajo del corte, está esperando los resultados de las discusiones de los comentarios rusos (sí, SUS comentarios sobre C ++ 20), algunos comentarios de otros países y, por supuesto, el nuevo C ++ 23 adecuado (¡Ejecutores!).
Todos esos problemas con C ++ que la gente mencionó en el sitio
stdcpp.ru , en el chat
@ProCxx , en el trabajo en Yandex.Taxi, o en persona en las conferencias, formalizamos en forma de comentarios en C ++ 20. Y entonces, ¿qué salió de eso ...
std :: atomic <int> a {}; y std :: atomic <int> b;
Puede parecer extraño, pero las variables
ayb no se inicializan a 0. Para inicializar una variable atómica a cero, fue necesario escribir exactamente std :: atomic <int> con {0};
Este comportamiento es completamente obvio, y muchos desarrolladores se quemaron. El comité aceptó nuestra observación sobre el estándar, y en C ++ 20, los constructores predeterminados para std :: atomic_flag y std :: atomic inicializarán las variables en
estado claro y T (), respectivamente.
std :: lavado
Comenzando con C ++ 17, el estándar tiene una función de miedo std :: launder. La gente del comité pensó que los desarrolladores de bibliotecas estándar y los usuarios comunes descubrirían cómo lidiar con eso.
En la práctica, resultó que en algunos casos esta función no se puede utilizar. Es extremadamente obvio que se necesita en principio:
struct C { const int c; }; std::vector<C> v = {C{1}}; v.pop_back(); v.push_back(C{2}); assert(v.back().c == 2);
Si sigue estrictamente la letra del estándar, dependiendo de la implementación de la biblioteca estándar, las características del compilador y la fase lunar, la afirmación puede pasar o fallar.
Cuando se discutió el problema, resultó que la optimización, por la cual el estándar describió un comportamiento tan extraño, se implementó solo en uno de los compiladores y no trajo un aumento tangible del rendimiento.
Entonces, comenzando con C ++ 20, puede almacenar de forma segura estructuras con enlaces y campos constantes en std :: opcional, std :: variante, std :: vector, std :: deque, etc. Ahora la colocación nueva aplica automáticamente parte de la lógica std: : lavado.
* esto en constructores
Este es uno de los comentarios donde nos esperaba un fracaso:
struct C { C(C&& other) noexcept : initial_(other.initial_) , secondary_(other.initial_)
De acuerdo con las reglas actuales, en la línea con
O_O, el compilador tiene el derecho de asumir que & other == this y, en consecuencia, una línea arriba, reescribimos el valor de other.initial_ y necesita ser releído.
En otras palabras, el compilador tiene el derecho de asumir que una clase que aún no se ha creado tiene un alias con el parámetro a partir del cual se construye el objeto, y debido a esto puede generar código no óptimo.
Algunos compiladores (por ejemplo, GCC) creen que los usuarios no escriben tal desgracia y creen que el aliasing no es posible.
El comité rechazó nuestra observación "Asumamos que el aliasing no es posible". Al final resultó que, algunas bases de código tienen trucos de miedo donde y otros == esto, y la gente aún no está lista para decirles adiós.
operador <=> y programación integrada
Para que el operador de la nave espacial funcione, necesita el archivo de encabezado <compare>. Sin embargo, no estaba en la lista de archivos de encabezado que están disponibles en ninguna plataforma (en las llamadas
implementaciones independientes de la biblioteca estándar que se pueden usar en cualquier plancha).
Ahora está en la lista :)
El resto
Según nuestros otros comentarios, se emitió el veredicto "No en C ++ 20":
* Queríamos que __func__ se usara en constexpr.
* Queríamos que el concepto no utilizara el tipo incompleto, porque de lo contrario obtendría múltiples violaciones de ODR. Pero la observación tuvo un efecto positivo inesperado: los compiladores ahora emiten una advertencia si utiliza el tipo incompleto en require.
* Queríamos corregir el operador de asignación para std :: string para que no ocurriera tal desorden:
basic_string::operator=(charT c): double d = 3.14; std::string s; s = d;
El comité sugirió escribir un documento separado y corregirlo después de C ++ 20.
* Queríamos eliminar la asignación de líneas temporales en std :: string_view:
std::string foo(); std::string_view sv; sv = foo();
El resultado es el mismo que el comentario anterior: el comité sugirió escribir un documento separado y corregirlo después de C ++ 20.
* Solicitamos que se compile el siguiente código:
#include <type_traits> template <typename... Xs> auto f (Xs...) -> std::invoke_result_t<Xs...>;
Nos dijeron que todo es complicado, prácticamente no hay posibilidad de reparar C ++ 20.
Comentarios de otros países
De los cambios significativos: agregar constructores para std :: span a partir de tipos que satisfacen el concepto de range :: contiguous_range. Así que ahora span se puede crear implícitamente a partir de std :: vector y std :: string. También agregamos el constructor std :: string_view de dos iteradores que satisfacen el concepto de range :: contiguous_iterator.
Ediciones divertidas esperaban <compare>. En los últimos tres años, el operador <=> ha cambiado mucho. Ya no participa en las comparaciones para la igualdad, y, en consecuencia, ya no se necesita un tercio del contenido de <compare>. Varios países se han dado cuenta de esto: han reducido el estándar.
Un gran cambio se coló en los parámetros de plantilla que no son de tipo. En C ++ 20, será posible pasar
casi cualquier clase (ver P1907) con un destructor constexpr y miembros públicos como parámetro de plantilla, incluso si la clase contiene tipos o enlaces de punto flotante.
También agregamos el const faltante a diferentes partes del estándar, cambiamos los nombres y el orden de los argumentos de algunas funciones nuevas para C ++ 20. También hay numerosas ediciones para conceptos y rangos, abreviaturas del texto estándar y otras pequeñas cosas.
Números TS
ZaMaZaN4iK y
yo pudimos agitar el comité con el documento C ++ Numerics Work In Progress. Ahora hay planes napoleónicos para que C ++ 23 ofrezca a los usuarios un conjunto de nuevos tipos de números (wide_integer, integer, racional), junto con métodos auxiliares de bajo nivel para trabajar con desbordamientos y alias convenientes.
Me dijeron que preparara una presentación para la próxima reunión con una introducción a las ideas para todo el comité.
Ejecutores
Los ejecutores es una de las prioridades de C ++ 23. Son necesarios para la programación reactiva, para la programación asincrónica (red, disco, procesos ...), son la base para la eliminación de la rutina y deben proporcionar una interfaz única para bibliotecas de terceros.
Al mismo tiempo, los ejecutores deben optimizar los algoritmos para su implementación interna. Por ejemplo, para el código:
template <std::input_range Range> void MySort(Range& data) { namespace stdr = std::ranges; std::sort(GetGlobalExecutor(), stdr::begin(data), stdr::end(data), 42); }
la función GetGlobalExecutor () puede devolver:
* Ejecutor de un solo subproceso: debe ejecutar el std :: sort habitual en su subproceso;
* ejecutor multiproceso: debe realizar una clasificación paralela;
* Ejecutor de GPU: debe mover los datos a la memoria de la tarjeta de video, ordenarlos allí y devolver los datos;
* Ejecutor NUMA - ...
* ...
Hasta ahora, para implementar dicha funcionalidad, debe hacer objetos de punto de personalización (CPO) de miedo, convertir cada algoritmo en ellos. Al comité no le gustó ...
Pero al menos
aprobaron previamente el P0443 , la interfaz básica. Todas las oraciones posteriores para los ejecutores deberán escribirse en forma de parches para P0443.
En lugar de totales
Ahora estamos separados de C ++ 20 por una sola reunión del comité. Solo queda un poco ...
Bueno, todos los que quieran chatear con representantes del comité en vivo: miren los mitaps y las conferencias de C ++
(*) :
*
Corehard en Minsk*
C ++ Siberia 2020*
C ++ Rusia 2020*
St. Grupo de usuarios de Petersburg C ++*
C ++ Meetup 2019 en Moscú(*) Life hack: no tienes que pagar un boleto de conferencia si eres un orador.