Encuentro el estilo de codificación en el STM32F0 (microcontrolador ARM Cortex-M0) SPL (biblioteca de periféricos estándar) innecesariamente detallado. Como ejemplo, aquí hay un fragmento de código para configurar el ciclo de bloqueo de fase para SYSCLK:
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
Donde RCC_CFGR_SW
y RCC_CFGR_SW_PLL
son macros para literales enteros ya convertidos a uint32_t
.
#define RCC_CFGR_SW ((uint32_t)0x00000003)
#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002)
Y RCC->CFGR
es una instancia (asignada en memoria) de una estructura del tipo
typedef struct
{
...
__IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x04 */
...
} RCC_TypeDef;
Entonces, el resultado se lanzaría implícitamente de uint32_t
todos modos, incluso dando una advertencia si sucede algo divertido (a diferencia de lo que sucedería con un lanzamiento explícito).
¿Pueden eliminarse estos lanzamientos explícitos, especialmente dado que C99 garantiza (6.3.1.3) que
Permitiendo la simplificación del código al significativamente más claro
//Select the PLL as system clock source
RCC->CFGR &= ~(RCC_CFGR_SW);
RCC->CFGR |= RCC_CFGR_SW_PLL;
¿O podría eso causar algunos efectos secundarios imprevistos? No estoy muy seguro, y supongo que las personas que escribieron ese código tienen más experiencia escribiendo C incrustado que yo...
Estoy haciendo esta pregunta en electronics.stackexchange en lugar de stackoverflow, ya que es bastante específico para la programación integrada de bajo nivel.
Ha pasado un tiempo desde que perdí el tiempo leyendo los estándares C. Pero hay una pista de todo eso que puede ser útil, en general. No creo que sea de mucha ayuda aquí, sin embargo. Permítanme decir lo que recuerdo y luego considerar si hay más comentarios. (Sin embargo, no estoy seguro de que este sea el lugar para buscar escritores de compiladores de C; y ellos son los que conocerían los detalles exactos).
Cuando C convierte un int con signo en un int sin signo, del mismo tamaño físico, el estándar requiere que el compilador de C produzca un resultado sin signo que (1) tenga el mismo significado de valor equivalente en el espacio de símbolos sin signo, o bien; (2) es el módulo de valor con signo . Tales conversiones tienen garantizado un resultado matemático específico. Uno que la mayoría de la gente espera, de hecho. Sin embargo, cuando un int sin signo se convierte en un int con signo, nuevamente del mismo tamaño físico, el estándar requiere que si y solo si existe un significado de valor equivalente , entonces ese significado debe mantenerse. Sin embargo, si el valor sin signo excede el límite de significado de valor positivo , entonces no hay ningún resultado estándar. El compilador de C puede, supongo, generar tonterías aleatorias si así lo desea.
Puede ser que la mano izquierda no sepa lo que está haciendo la mano derecha en la codificación que está viendo. Puedes ir a mirar, por supuesto, y ver lo obvio. Pero es posible que aquellos que escriben las expresiones estén tratando de estar a la defensiva en el sentido de que alguien podría volver a escribir una constante de lo que solía ser un valor sin signo a un valor con signo (o por defecto, con signo). (A los compiladores de C se les permite, o se les permitía, hacer sus propias elecciones predeterminadas cuando el especificador firmado o no firmado estaba ausente. Y si no estaban permitidos, algunos ciertamente lo hicieron de todos modos).
Lanzar cosas a unsigned siempre garantiza un resultado específico. Así que es más seguro de usar. O lo fue una vez, cuando estaba leyendo los estándares hace años. En caso de que alguien haya usado explícitamente, o por defecto del compilador, un valor firmado.
Dicho todo esto, no puedo recordar un compilador de C que haya hecho algo loco al convertir un int sin firmar en un int con signo. En general, asumiendo que el hardware de la computadora usó la notación habitual de complemento a dos, todos hacen lo obvio y los hacen idénticos a nivel de bits. Es sólo la interpretación que cambia, más tarde. Pero eso no significa que a alguien que realmente haya leído los estándares le importe; podría decidir escribir como si hubiera un compilador de C loco por ahí. Solo para demostrar que habían leído el estándar.
Ahora, no he considerado el código que muestra en el contexto de instancias de diferentes tamaños. Pero lo anterior podría darle una pista sobre por qué está viendo esas cosas allí.
PlasmaHH
Armanda
tubo
Arsenal
robert bristow-johnson
RCC->CFGR
también lo seauint32_t
, las conversiones en las dos primeras declaraciones son totalmente redundantes. hay muchos programadores de mierda que no se dan cuenta de que, además de hacer un código que funcione, también es importante hacer un código conciso, legible y fácil de mantener.usuario207421
Pedro Smith