Aquí se ha preguntado bastante si se permiten índices negativos en C, pero tengo curiosidad por saber si hay alguna desventaja en el rendimiento al usar esta técnica con frecuencia. Por ejemplo, ¿interrumpe la capacidad del compilador para usar la indexación de base + compensación en alguna plataforma de hardware en algún lugar, o confunde al optimizador, etc.
Pregunto porque tengo muchas rutinas de decodificación con la firma de
decode_something(char *buffer, int buffer_size, int bit_position) { ... if (((bit_position + need_bits) >> 3) < buffer_size) { x= buffer[bit_position >> 3] ... bit_position += need_bits; ... }y me di cuenta de que puedo simplificar enormemente todo ese código si uso un puntero al final del búfer:
decode_something(char *buf_limit, int bits_remaining) { ... if (need_bits <= bits_remaining) { x= buf_limit[ -((bits_remaining+7) >> 3) ]; bits_remaining -= need_bits; ... }(bueno, en realidad este ejemplo no muestra cómo se vuelve "mucho" más simple, pero puede extrapolar a todos los casos en los que llamar a esta función o guardar el estado de análisis solo requiere dos variables en lugar de tres).
Ahora estoy considerando usar este patrón en toda una biblioteca, pero quería saber si hay alguna razón para no hacerlo.
Por ejemplo, ¿interrumpe la capacidad del compilador para usar la indexación de base + compensación en alguna plataforma de hardware en algún lugar, o confunde al optimizador, etc.
No. El estándar del lenguaje C lo define claramente:
Del Estándar C11#6.5.6p8:
8 Cuando se suma o se resta de un puntero una expresión de tipo entero, el resultado tiene el tipo del operando del puntero. Si el operando puntero apunta a un elemento de un objeto de matriz, y la matriz es lo suficientemente grande, el resultado apunta a un elemento desplazado del elemento original de tal manera que la diferencia de los subíndices de los elementos de la matriz resultante y original es igual a la expresión entera. En otras palabras, si la expresión P apunta al i-ésimo elemento de un objeto de matriz, las expresiones (P)+N (equivalentemente, N+(P)) y (P)-N (donde N tiene el valor n) apuntan a, respectivamente, los elementos i+n-th y in-th del objeto de matriz, siempre que existan. ....
Por si acaso, si no lo sabes:
De C11 Standard#6.5.2.1p2, la definición de operador de subíndice:
La definición del operador de subíndice [] es que E1[E2] es idéntico a (*((E1)+(E2))).
Tu otra pregunta:
pero tengo curiosidad de que haya alguna desventaja en el rendimiento al usar esta técnica con frecuencia.
Se reduce a una pregunta: hay dos números a y b , de estas dos operaciones: a + b y a - b , cuya operación es más rápida que otra.
No es el idioma el que dicta el tiempo para operaciones como sumas, restas, etc., sino el procesador subyacente. Si está realmente interesado en él, debe profundizar en el conjunto de instrucciones del procesador subyacente y comparar la latencia de las instrucciones respectivas, etc.