Conversion entre uint8 et char en C

J’ai une API qui implémente une opération d’écriture sur EEPROM. Voici sa déclaration:

CYBLE_API_RESULT_T CyBle_StoreAppData (uint8 * srcBuff, const uint8 destAddr[], uint32 buffLen, uint8 isForceWrite); 

Cela fonctionne bien quand j’appelle cette fonction et envoie un paramètre de tableau à srcBuff qui a été déclaré comme type uint8 .

Le problème est que je dois lui envoyer un pointeur sur un tableau de caractères. Je pensais que char est déjà un uint8 , mais je reçois un avertissement du compilateur si j’envoie un pointeur de tableau de caractères à cette fonction au lieu de uint8 . Pourquoi ne puis-je pas utiliser char au lieu de uint8 ? Voici 2 exemples d’appel de cette fonction:

 static const uint8 datastack_ROM[dedicatedRomSize] = {0}; uint8 Container_ID[10]; char Prefix[10]; //Call the function with Container_ID which has been declared as uint8. This is working. CyBle_StoreAppData(Container_ID,datastack_ROM,10,0); //Call the function with Prefix which has been declared as char. This is NOT working. CyBle_StoreAppData(Prefix,datastack_ROM,10,0); 

Voici l’avertissement pour le deuxième appel:

passing char[10] to parameter of type 'uint8 *' converts between pointers to integer types with different sign.

uint8 et uint8 ne sont-ils pas identiques?

Les deux types ont une longueur de 8 bits. La différence vient avec la signature.

  • Le type uint8 n’est pas signé.
  • Le type de caractère doit être signé dans votre cas. En réalité, il dépend du compilateur, mais la plupart des compilateurs considèrent le type de caractère comme signé par défaut et disposent d’une option pour forcer le type de caractère comme non signé si nécessaire. Voir la référence de document standard C99 §6.2.5p15:

L’implémentation doit définir char pour avoir la même plage, la même représentation et le même comportement que char signé ou non signé.

CHAR_MIN, défini dans limits.h, aura l’une des valeurs 0 ou SCHAR_MIN, ce qui peut être utilisé pour distinguer les deux options.

 uint8 Container_ID[10]; 

C’est un entier non signé de 8 bits avec des valeurs possibles de 0 à 255

 char Prefix[10]; 

Dans votre cas, un caractère signé de 8 bits avec des valeurs entières de -127 à +128

Comme ils ne sont pas du même type de signe, vous recevez un avertissement de conversion, comme vous le devriez.

char et uint8 ont tous les deux quelque chose en commun et c’est important: ce sont deux entiers de 8 bits. Maintenant deux questions

  • est / est-ce / ces 8 bits entiers signés ou non signés?

Et plus important

  • est-ce important dans votre cas?

Par exemple, voulez-vous envoyer à la fonction un tableau composé d’entiers pour lesquels il est important de les considérer comme signés? Par exemple, si la fonction ferait quelque chose comme ça,

 if (charvalue < 0) { ... 

ou si vous voulez que la fonction soit attentive à la signature des octets (si cela est possible); si la fonction le faisait et que le signe importait: envoyer un 255 est positif, mais vu l'octet signé, cela serait interprété comme -1 ...

Mais cela n’a aucun sens puisque la fonction prend uint8 * (les développeurs auraient peut-être utilisé char pour traiter les octets individuellement et utiliser leur signature, mais dans ce cas, avoir une signature de fonction comme celle-ci serait très trompeur!)

Donc, la E 2 PROM traite les octets non signés, et vous pouvez en toute sécurité convertir le pointeur atsortingbué à la fonction pour supprimer l’avertissement,

 CyBle_StoreAppData((uint8 *)Prefix,datastack_ROM,10,0); 

ou simplement

 uint8 Prefix[10]; 

si cela ne pose pas d'autres problèmes / avertissement avec le rest de votre code.

uint8_t est très probablement défini comme un caractère non signé.

char est son propre type qui se comporte exactement comme les caractères signés ou non signés (Remarque, ce sont trois types distincts).

Dans ce cas, il se comporte comme un caractère signé et vous obtenez un avertissement de conversion.