La lista de cambios en D 2.092. Préstamo Préstamo

Del traductor. Por lo general, no traduzco tales artículos, porque no veo nada interesante en ellos. Aquí, dos pequeñas pero importantes innovaciones: soporte para la vinculación directa de bibliotecas C ++ y el sistema de propiedad `` prestado '' y préstamos de Rust (la segunda es la ingestión de DFA, la primera salió en GCC10 hace solo un par de días, y Nim también lo piensa así) con una descripción. En realidad, no traduje ninguna lista tediosa, y los enlaces conducen al original.

La versión anterior de la lista 2.0.91.1 (inglés)
Dónde descargar

2.092.0 salió con 15 cambios importantes y 44 correcciones de errores y mejoras. Muchas gracias a los 47 colaboradores que hicieron posible este lanzamiento.

Cambios del compilador


  1. Los modificadores de línea de comando -revert = import and -transition = checkimports eliminados
  2. Soporte agregado para la codificación (cambio) de nombres ABI C ++ GNU
  3. Los constructores y destructores para módulos que no son externos (D) están marcados como obsoletos
  4. Violaciones DIP25 marcadas por defecto obsoletas
  5. Sistema de propiedad y préstamo de prototipos para punteros
  6. Añadido = -preview en la opción que convierte a la clase de almacenamiento en en const alcance
  7. Los parámetros printf y scanf ahora se verifican para verificar el cumplimiento de los especificadores de formato
  8. La variable de entorno SOURCE_DATE_EPOCH ahora es compatible.

Cambios de tiempo de ejecución


  1. TypeInfo_Class/TypeInfo_Interface.isBaseOf C#/Java isAssignableFrom
  2. core.memory.pageSize minimumPageSize


  1. Date.isoWeekYear Date.fromISOWeek std.datetime.date
  2. std.xml
  3. std.digest.digest

Dub


  1. Dub lint --report-file

Una lista completa de correcciones y mejoras (Esp.)

Nota: tengo patas, por lo tanto, no es posible configurar enlaces correctos dentro de la página desde la tabla de contenido para revelar los temas en el original, lo siento = (

Cambios del compilador


  1. La línea de comando cambia -revert = import y -transition = checkimports han sido eliminados.

    Estas teclas no hicieron nada, y durante algún tiempo se marcaron como obsoletas. El compilador ya no los reconocerá.
  2. () C++ GNU ABI

    GNU ABI C++11 GCC 5.1. D C++, DMD UDA ( ) gnuAbiTag, core.attribute object ( ). ABI , , ++ . , std::string C++11 (DMD -extern-std={c++11,c++14,c++17}).

    :

    extern(C++):
    @gnuAbiTag("tagOnStruct")
    struct MyStruct {}
    @gnuAbiTag("Multiple", "Tags", "On", "Function")
    MyStruct func();

    gnuAbiTag. ( ). UDA -extern-std=c++11. (-extern-std=c++98) UDA . UDA extern(C++) .
  3. , extern(D) .

    ( ) , extern(D), . , , / , , 479, 479, .

    , , .
  4. DIP25 .

    DIP25 2.067.0, , -preview=dip25. , , DIP1000.

    , , -preview=dip25, -preview=dip25. ( ).

    DIP25 , @ safe . , ref , return , .

    struct Foo
    {
        int x;
        // returning `this.x` escapes a reference to parameter `this`, perhaps annotate with `return`
        ref int method() /* return */ { return this.x; }
    }
    // returning `v` escapes a reference to parameter `v`, perhaps annotate with `return`
    ref int identity(/* return */ ref int v) { return v; }

    return . DIP25 .
  5. -preview=in in scope const.

    const scope, in . , in (. inout ) .

    -preview=in, :

    void fun(in int x);
    void fun(const int x);

    -preview=in, :

    void fun(in int x);
    void fun(scope const int x);
  6. printf scanf

    C99 7.19.6.1 printf 7.19.6.2 scanf.

    printf , . , .

    scanf .

    :

    1. ,
    2. ,
    3. — , s
    4. C99

    -, .

    .

    , printf/scanf, :

    printf("%k\n", value);  // error: non-Standard format k
    const format = "%k\n";
    printf(format.ptr, value);  // no error

    — . ,

    string s;
    printf("%.*s\n", s.length, s.ptr);
    printf("%d\n", s.sizeof);
    ulong u;
    scanf("%lld%*c\n", &u);

    :

    string s;
    printf("%.*s\n", cast(int) s.length, s.ptr);
    printf("%zd\n", s.sizeof);
    ulong u;
    scanf("%llu%*c\n", &u);

    printf scanf pragma(printf) printf pragma(scanf) scanf.

    , :

    1. extern (C ) extern (C++)
    2. const(char)*
    3. … -v , va_list ( «v» printf scanf)
    .

    «v»- .
  7. SOURCE_DATE_EPOCH

    SOURCE_DATE_EPOCH. UNIX ( 1970-01-01 00:00:00), . DMD __DATE__, __TIME__ __TIMESTAMP__ .



El sistema de propiedad / préstamo (también conocido como OB) para punteros garantiza que los punteros desreferenciados apunten a un objeto de memoria válido.

Alcance del prototipo de sistema OB


Este es un prototipo del sistema OB, adaptado para D. Inicialmente, está destinado solo a punteros, y no a matrices dinámicas, referencias de clase, referencias o campos de puntero en agregados. Agregar soporte de este tipo complicará la implementación, pero no cambia su esencia, por lo tanto, se pospone para más adelante. Los objetos RAII pueden administrar de forma segura su propia memoria, por lo que no están cubiertos por OB. Independientemente del método, ya sea que el puntero asigne memoria mediante GC o algún otro asignador, esto no es importante para el OB, no difieren y se procesan de manera idéntica.

El sistema OB está activo solo en funciones anotadas con el atributo @ live. Se aplica después del procesamiento semántico únicamente como un control de violación de las reglas de las sustancias orgánicas. No se agrega nueva sintaxis. No se realizan cambios en el código generado. Si @ vivos funciones llaman funciones distintas de @ en vivo , se espera que estas llamadas funciones serán un @ LIVE- interfaz compatible, aunque no se ha probado. Si las funciones que no son @ live llaman a las funciones @ live , se espera que los argumentos pasados ​​sigan las convenciones @ live .

El sistema OB detecta errores:

  • desreferenciar punteros que están en un estado no válido
  • más de un puntero activo a un objeto de memoria mutado.

No detectará intentos de desreferenciar un puntero nulo o, potencialmente, un puntero nulo. Esto no funciona, ya que actualmente no existe un método para anotar un tipo como puntero no anulable.

El principio básico de OB


El diseño OB se desprende del siguiente principio:

Para cada objeto de memoria, puede haber exactamente un puntero mutante o varios punteros no mutantes (solo lectura).

Diseño


Un puntero mutante único se llama el "propietario" del objeto de memoria. Posee de forma transitiva un objeto de memoria y todos los objetos en memoria accesibles desde él (es decir, la gráfica de objetos). Dado que es el único puntero a este objeto de memoria, puede administrar la memoria de manera segura (cambiar su forma, asignar, liberar y cambiar el tamaño) sin golpear el suelo debajo de los pies de cualquier otro puntero (mutante o no) que pueda estar en él (gráfico memoria) indicar.

Si hay varios punteros en un gráfico de objetos de memoria que son de solo lectura, entonces pueden leer de forma segura sin preocuparse por los cambios repentinos en el gráfico de objetos en la memoria.

El resto de los detalles de la tecnología se relacionan con cómo los punteros se vuelven de solo lectura y no válidos, y cómo se mantiene constantemente el Principio Central de OB.

Punteros rastreados
Solo se rastrean los punteros que se declaran en la función @ live como esto , parámetros de función o variables locales. Las variables de otras funciones no se rastrean, incluso @ live , ya que el análisis de las interacciones con otras funciones depende completamente solo de la firma de esta función, y no de sus componentes internos. Los parámetros que son constantes no se rastrean.

Estados del
puntero Cada puntero se encuentra en uno de los siguientes estados:

Indefinido
El puntero está en un estado no válido. Desreferenciar tal puntero es un error.
Propietario El
propietario es el único puntero a un gráfico de objetos en la memoria. Por lo general, un puntero: el propietario no tiene un atributo de alcance . Si el puntero con el atributo de ámbito se inicializa con una expresión que no se deriva del puntero rastreado, se convierte en el Propietario.
Si el puntero Propietario se asigna a otro puntero, el Propietario, el primero pasa al estado Indefinido.
Prestado
Un puntero prestado es un puntero que se convierte temporalmente en el único puntero a un gráfico de objetos de memoria. Él pasa a este estado mediante la asignación del puntero: el Propietario, mientras que el Propietario pasa al estado del Prestatario hasta que se complete el uso del puntero prestado.
Un puntero prestado debe tener un atributo de alcance y ser un puntero a un objeto mutable. Solo
lectura
El propietario asigna el índice de solo lectura . Mientras el puntero de solo lectura esté activo, solo se pueden asignar punteros de solo lectura desde este propietario. El puntero de solo lectura debe tener un atributo de alcance , y tampoco debe ser un puntero a un objeto mutable.

Vidas

La vida útil del indicador "Prestado" o "Solo lectura" comienza desde el momento en que se desreferencia por primera vez (y no desde el momento en que se inicializa o se le asigna un valor) y termina cuando el valor se desreferencia por última vez.

También se conoce como vidas no léxicas .

Transiciones de estado para punteros

Un puntero cambia su estado cuando se realiza una de estas operaciones:

  • se le asigna memoria (por ejemplo, una variable local en la pila), que coloca el puntero en un estado indefinido
  • Inicialización (considerada como asignación)
  • asignación: los punteros de origen y destino cambian de estado dependiendo de en qué estados se encuentren, así como de sus tipos y clases de almacenamiento
  • out ( ), , .
  • ref , , .
  • , .
  • - ()
  • , , .
  • , ,
  • , ,
  • ,


Al ser un prototipo, hay muchos aspectos que aún no se han considerado, y no lo serán hasta que el prototipo demuestre que esta es una solución viable.

Errores

Espere muchos errores. Por favor repórtelos a bugzilla y etiquételos con la palabra clave "ob". No es necesario informar otras restricciones que ya se enumeran aquí.

Las referencias a clases y matrices asociativas no se rastrean.
Se supone que están controlados por el GC.

Préstamo y lectura de no propietarios Los

propietarios son monitoreados para detectar fugas, pero no otros indicadores. Los prestatarios se consideran propietarios si no se inicializan con un puntero.

@live void uhoh()
{
    scope p = malloc();  // p is considered an Owner
    scope const pc = malloc(); // pc is not considered an Owner
} // dangling pointer pc is not detected on exit

Parecería que no tiene sentido marcar punteros como el alcance , quizás esto se pueda solucionar tratando esto como un error.

Los punteros son leídos / escritos por funciones anidadas
.

@live void ohno()
{
    auto p = malloc();

    void sneaky() { free(p); }

    sneaky();
    free(p);  // double free not detected
}

El

análisis de excepciones supone que no se lanzan excepciones.

@live void leaky()
{
    auto p = malloc();
    pitcher();  // throws exception, p leaks
    free(p);
}

Una solución es usar el alcance (salir) :

@live void waterTight()
{
    auto p = malloc();
    scope(exit) free(p);
    pitcher();
}

use objetos RAII o solo llame a funciones nothrow.

Parámetros diferidos

No se tienen en cuenta.

Complejidad cuadrática El

análisis muestra la complejidad cuadrática; intente mantener pequeñas las funciones @ live .

Mezcla de diferentes grupos de memoria

Combinación de diferentes grupos de memoria:

void* xmalloc(size_t);
void xfree(void*);

void* ymalloc(size_t);
void yfree(void*);

auto p = xmalloc(20);
yfree(p);  // should call xfree() instead

no detectado.

Esto se puede evitar utilizando grupos específicos para un tipo particular:

U* umalloc();
void ufree(U*);

V* vmalloc();
void vfree(V*);

auto p = umalloc();
vfree(p);  // type mismatch

y posiblemente no permita conversiones implícitas a void * en las funciones @ live .

Argumentos de una función variable Los

argumentos de una función variable (por ejemplo, printf) se consideran consumidos. Si bien esto es seguro, no parece ser muy práctico y probablemente requerirá una revisión.

Cambios de tiempo de ejecución


  1. TypeInfo_Class/TypeInfo_Interface.isBaseOf C#/Java isAssignableFrom.

    TypeInfo_Class.isBaseOf true, , , , . isBaseOf, isAssignableFrom, , opAssign D — . TypeInfo_Interface.isBaseOf , TypeInfo_Class, TypeInfo_Interface.
  2. core.memory.pageSize minimumPageSize.

    pageSize .

    import core.memory : pageSize;
    ubyte[] buffer = new ubyte[pageSize];

    minimumPageSize .

    , . , . pageSize, .

    , , , : ubyte[minimumPageSize].

    import core.memory : minimumPageSize;
    ubyte[minimumPageSize] buffer;



  1. Date.isoWeekYear Date.fromISOWeek std.datetime.date

    ISO 8601 , Date and DateTime.

    ISO , . Date.fromISOWeek(2020, 11, DayOfWeek.mon) Date(2020, 3, 9).

    ISO , () .isoWeekYear Date ISO. , .isoWeekAndYear , .
  2. std.xml .

    std.xml . , , UndeaD. xml dub- dxml.
  3. std.digest.digest .

    2.076.1 . std.digest .

    std.digest.digest 2.101.

Dub


  1. .

    Posix , .dub. dub (, .swap.file.d), . , dub . , dub.

    , .
  2. Dub lint --report-file.

    Dub lint --report-file: dub lint --report-file report.json

All Articles