attributs redondants __packed__
-
01-10-2019 - |
Question
Ce code est pour le microprocesseur PIC32MX de Microchip. Leur compilateur est essentiellement GCC 3.4.
Je tends d'utiliser GCC __packed__
attribut pour emballer bitfields dans une union, et plus tard les récupérer comme unsigned char
(ie. de type calembour) pour l'envoi sur SPI ou I2C. Ce comportement est tout défini par ma mise en œuvre, et fonctionne parfaitement. Je préfère ceci à une centaine de lignes de masquage et de décalage:)
Ma question est: Y at-il des attributs __packed__
dans le code ci-dessous qui sont redondants? À première vue, je pense que ceux des membres du syndicat niveau supérieur peut se passer, mais je ne suis pas si sûr. Ou puis-je laisser de côté ceux de la struct imbriqué?
// Remember that bitfields cannot straddle word boundaries!
typedef struct
{
/// Some flag #1
unsigned FlagOne : 1 __attribute__((packed));
/// Some flag #2
unsigned FlagTwo : 1 __attribute__((packed));
/// A chunk of data
unsigned SomeData : 5 __attribute__((packed));
// and so on, maybe up to 32 bits long depending on the destination
} BlobForSomeChip;
/// This kind of type-punning is implementation defined. Read Appendix A (A7, A12) of
/// the MPLAB C Compiler for PIC32 MCUs manual.
typedef union
{
/// Access the members of this union to set flags, etc
BlobForSomeChip blobdata __attribute__((packed));
/// As a byte for sending via SPI, I2C etc
unsigned char bytes[4] __attribute__((packed));
} BlobData;
La solution
Tout d'abord, je vous recommande la compilation avec -Wall
.
- Le struct
BlobForSomeChip
a 7 bits déclarées. Normalement, ce serait 4 octets en raison de l'alignement, mais avec des attributs niquent sera seulement 1 octet longue. - Un
unsigned char[4]
ne peut pas être emballé. Il sera toujours 4 octets, peu importe.
En bref:
-
struct BlobForSomeChip
= 1 octet -
unsigned char[4]
= 4 octets -
BlobData
= 4 octets (taille de son plus grand membre).
En conclusion, les attributs emballés sur BlobData
ne sont pas nécessaires. GCC simplement les ignorer si -. Voir la sortie en utilisant -Wall