llamada a la función con el puntero a no constante y el puntero a los argumentos de tipo const misma dirección

Willy:

Quiero escribir una función que introducir una serie de datos y salida de otra serie de datos utilizando punteros.

Me pregunto cuál es el resultado si ambos srcy dsten punta a la misma dirección, porque sé compilador puede optimizar para la const. ¿Es indefinido comportamiento? (I tagged tanto C como C ++, porque no estoy seguro de si la respuesta puede diferir entre ellos, y yo quiero saber de ambos).

void f(const char *src, char *dst) {
    dst[2] = src[0];
    dst[1] = src[1];
    dst[0] = src[2];
}

int main() {
    char s[] = "123";
    f(s,s);
    printf("%s\n", s);
    return 0;
}

Además de la pregunta anterior, es este bien definido si elimino el consten el código original?

einpoklum:

Si bien es cierto que el comportamiento está bien definido - es no cierto que los compiladores pueden "optimizar para la const" en el sentido de que usted se refiere.

Es decir, es un compilador no permitió asumir que sólo porque un parámetro es una const T* ptr, la memoria a la que apunta ptrno será cambiado por otro puntero. Los punteros ni siquiera tienen que ser iguales. El constes una obligación, no una garantía - la obligación por usted (= la función) de no hacer cambios a través de ese puntero.

Con el fin de tener en realidad esa garantía, es necesario marcar el puntero con la restrictpalabra clave. Por lo tanto, si se compila estas dos funciones:

int foo(const int* x, int* y) {
    int result = *x;
    (*y)++;
    return result + *x;
}

int bar(const int* x, int* restrict y) {
    int result = *x;
    (*y)++;
    return result + *x;
}

la foo()función debe leer dos veces x, mientras que bar()sólo tiene que leer una vez:

foo:
        mov     eax, DWORD PTR [rdi]
        add     DWORD PTR [rsi], 1
        add     eax, DWORD PTR [rdi]  # second read
        ret
bar:
        mov     eax, DWORD PTR [rdi]
        add     DWORD PTR [rsi], 1
        add     eax, eax              # no second read
        ret

Ver esto en vivo GodBolt.

restrictsólo es una palabra clave en C (desde C99); por desgracia, no ha sido introducida en C ++ hasta el momento (para los pobres razón por la que más complicado para introducirlo en C ++). Muchos compiladores un poco de apoyo que, sin embargo, como __restrict.

En pocas palabras: El compilador debe apoyar su caso "esotérica" se utiliza para compilar f(), y no tendrá ningún problema con él.


Ver este post con respecto a los casos de uso para restrict.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=369527&siteId=1
Recomendado
Clasificación