7
votes

Type Spécifications dans la plate-forme ABIS

Lequel de ces éléments peut être supposé être défini dans toute plate-forme pratiquement utilisable ABI?

  1. valeur de char_bit

  2. taille, exigences d'alignement et représentation d'objets de:

    1. void * , taille_t , pTRIFF_T
    2. non signé Char et signé Char
    3. intPTR_T et uintptr_t
    4. float , double et Double long
    5. court et long long
    6. int et long (mais ici, je m'attends à un "non")
    7. Pointeur à un type d'objet pour lequel la plate-forme ABI spécifie ces propriétés
    8. Pointeur sur la fonction dont le type implique uniquement des types pour lesquels la plate-forme ABI spécifie ces propriétés
    9. Représentation d'objet d'un pointeur d'objet NULL

    10. Représentation d'objet d'un pointeur de fonction NULL

      Par exemple, si j'ai une bibliothèque (compilée par un compilateur inconnu, mais abi-conformateur) qui publie cette fonction: xxx

      puis-je supposer Pour pouvoir l'appeler en toute sécurité dans mon programme, quel que soit le compilateur que j'utilise?

      ou, pris l'inverse, si je rédige une bibliothèque, existe-t-il un ensemble de types si je limite si je limite L'interface publique de la bibliothèque à cet ensemble sera garantie d'être utilisable sur toutes les plates-formes où elle construit?


0 commentaires

3 Réponses :


3
votes

Je ne vois pas comment vous pouvez vous attendre à une bibliothèque d'être universellement compatible. Si cela était possible, il n'y aurait pas tant de variations compilées de bibliothèques.

Par exemple, vous pourriez em> appelle une bibliothèque de 64 bits à partir d'un programme de 16 bits tant que vous avez configuré le appeler correctement. Mais vous devriez savoir que vous appelez une bibliothèque basée sur 64 bits. P>

La portabilité est un objectif très discuté, mais peu de choses y parviennent vraiment. Après 30 ans de plus de 30 ans de programmation au niveau du système, du micrologiciel et des applications, j'y pense en tant que fantaisie par rapport à un objectif. Malheureusement, le matériel nous oblige à optimiser pour le matériel. Par conséquent, lorsque j'écris une bibliothèque, j'utilise ce qui suit: p>

  1. Compilez pour ABI LI>
  2. Utilisez un pointeur sur une structure pour entrée et sortie pour tous les appels de fonction: P>

       int lib_func32(struct *input32, struct *output32)
       {
       struct input64;
       struct output64;
       int    retval;
    
           lib_convert32_to_64(input32, &input64);
    
           retval = lib_func64(&input64, &output64);
    
           lib_convert64_to_32(&output64, output32);
    
           return(retval);
       }
    


6 commentaires

Merci pour une bonne réponse. La fonction init est une idée intéressante, je n'aurais pas pensé à cela. Néanmoins, vous traitez uniquement de types de "plaines". Diriez-vous que taille_t et ptrdiff_t serait plus susceptible d'avoir la même taille dans différents compilateurs sur la même plate-forme exacte? Je comprends que 100% de certitude est impossible, mais si le compilateur X utilise une taille différente pour eux, c'est un compilateur étrange "être considéré comme une déclaration raisonnable? Ou sont-ils totalement imprévisibles aussi bien?


Les fabricants de compilateurs suivent les spécifications en ce qui concerne les types de données. Je ne m'inquiéterais pas pour ça. J'ai trouvé l'alignement pour être la plus grande erreur des utilisateurs de l'erreur. Vous devez inclure une instruction Align dans vos fichiers d'en-tête pour être sûr. La seule façon de voir différentes tailles sur la "même plate-forme" est si une personne compose de 32 bits mais à l'aide d'un compilateur 64 bits. Mais dans ce cas, votre fichier d'en-tête fourni à votre utilisateur doit détecter un environnement 32 bits et fonctionner en conséquence.


BTW, je ne peux imaginer aucune circonstance où la taille d'un pointeur serait différente lors d'une compilation donnée. Utilisation de Tailleof (Char *) vous indiquera toujours la taille de Tous les pointeurs .


En outre, en utilisant des structures pour l'entrée et la sortie, vous obtenez de nombreux avantages: 1. Vous pouvez transmettre autant de données à votre guise. 2. Les utilisateurs comprennent la lib immédiatement. 3. Les structures que vous définissez peuvent avoir des noms de membre auto-documentant. 4. Avec ABI, les structures sont dans les registres DI et SI à votre entrée. 5. Les nouvelles versions de votre bibliothèque peuvent simplement ajouter des membres aux structures au lieu de modifier les appels de fonction existants ou d'ajouter de nouvelles fonctions. (Inclure une taille de membre de structure dans toutes les structures - agit comme un numéro de version de structure.)


Je ne suis pas inquiet pour les fabricants de compilateurs qui ne suivent pas les spécifications. Ma question était (comme je n'ai aucune expérience de codage pour une grande variété de plates-formes), qu'il est prudent de s'attendre à ce que tout Sain ABI définit la taille de Taille_t et pTRDIFF_T . Et leur représentation d'alignement et d'objet.


En ce qui concerne les différentes tailles de pointeur, je crois (partiellement basée sur cette réponse ) qu'elles sont effectivement possibles sur du matériel. Néanmoins, char * est garanti pour être suffisamment grand pour tout pointeur - car il est de la même taille que vide * et void * est garanti à être assez grand pour n'importe quelle valeur de pointeur d'objet.



1
votes

Si je comprends vos besoins correctement, ceux de style UINT sont les seuls qui vous donneront une garantie de compatibilité binaire et de la cause INT, de l'impact, mais d'autres ont tendance à différer. i.e long sous Windows et Linux, Windows le considère comme 4byte et Linux sous forme de 8.byte. Si vous dépendez vraiment de ABI, vous devez planifier les plates-formes que vous allez livrer et utiliser Typedef S pour rendre les choses standardisées et lisibles.


0 commentaires

2
votes

La norme C contient une section entière de l'annexe qui résume celle-ci:

J.3 Comportement défini sur la mise en œuvre

Un sous-ensemble entièrement aléatoire:

  • Le nombre de bits dans un octet

  • Lequel de signé Char et non signé caractère est identique à char

  • Les codages de texte pour les chaînes multibytes et larges

  • Représentation entier signée

  • Le résultat de la conversion d'un pointeur en un entier et vice versa (6.3.2.3). Notez que cela signifie tout pointeur , pas seulement des pointeurs d'objet.


    mise à jour: Pour répondre à votre question sur ABIS: une interface binaire ABI (application d'application) n'est pas un concept standardisé, et il n'est pas dit nulle part où une mise en œuvre doit même spécifier une ABI. Les ingrédients d'un ABI sont en partie du comportement défini par la mise en œuvre de la langue (bien que tout non plus; par exemple, une conversion signée à non signé est définie, mais ne faisant pas partie d'une ABI) et la plupart des aspects définis par la mise en œuvre de La langue est dictée par le matériel (par exemple, représentation entière signée, représentation de points flottante, taille des pointeurs).

    Cependant, des aspects plus importants d'une ABI sont des éléments tels que la fonction appelle à la fonction fonctionnent, c'est-à-dire où les arguments sont stockés, qui est responsable du nettoyage de la mémoire, etc. Il est crucial que deux compilateurs s'entendent sur ces conventions pour leur code est binivement compatible.

    En pratique, un ABI est généralement le résultat d'une implémentation. Une fois que le compilateur est terminé, il détermine - en vertu de sa mise en œuvre - une ABI. Il peut documenter cet ABI, ainsi que d'autres compilateurs et les futures versions du même compilateur, peuvent aimer coller à ces conventions. Pour les implémentations C sur X86, cela a été très bien fonctionné et il n'y a que quelques paramètres gratuits, généralement bien documentés, qui doivent être communiqués pour que le code soient interopérables. Mais pour d'autres langues, notamment C ++, vous avez une image complètement différente: il n'y a rien de venir près d'une ABI standard pour C ++ du tout. Le compilateur de Microsoft brise le C ++ ABI avec chaque libération. GCC tente difficile de maintenir la compatibilité abi à travers les versions et utilise l'itanium abi publié (ironiquement pour une architecture désormais morte). D'autres compilateurs peuvent faire leur propre chose, complètement différente. (Et ensuite, vous avez des problèmes de bibliothèque standard C ++ les implémentations , par exemple votre chaîne contiennent un, deux ou trois pointeurs, et dans quel ordre?)

    Résumer: De nombreux aspects de l'ABI d'un compilateur, en particulier de C, sont dictés par l'architecture matérielle. Différents compilateurs C pour le même matériel devraient produire du code binaire compatible aussi longtemps que certains aspects tels que la fonction Les conventions appelantes sont correctement communiquées. Cependant, pour des langues de niveau supérieur, tous les paris sont désactivés et si deux compilateurs différents peuvent produire du code interopérable doivent être décidés au cas par cas.


6 commentaires

Merci. Je suis bien conscient que tous ces éléments sont définis par la mise en œuvre. C'est pourquoi je faisais référence à ABIS, pas à la norme. Ma question est de savoir s'il est raisonnable de s'attendre à ce que toutes les implémentations saines sur chaque plate-forme définissent (un sous-ensemble de) ce comportement de la même manière.


@Angew: Droite, je vois. Je ne pense pas que même la notion de "abi" elle-même est de quelque manière que ce soit normalisé, c'est-à-dire que la langue ne dit même pas que "vous spécifierez un abi". La plupart des propriétés que vous avez énumérées sont essentiellement déterminées par le matériel afin que vous puissiez vous attendre à ce que les compilateurs pour le même matériel soient d'accord sur ceux-ci, d'autres peuvent simplement être folkloriques (comme IA32 Conventions d'appel).


Je sais que "ABI" n'est pas un terme standard non plus. Néanmoins, la façon dont je comprends, dans une combinaison matérielle + OS, généralement l'une d'elles (ou ensemble) définit un abi. Je suis vraiment après "lequel de ces types pouvez-je m'attendre à ce que tel un ABI puisse définir?"


@Angew: Eh bien, c'est une standard terme , mais ce n'est pas un concept standardisé de quelque manière que ce soit. Un compilateur définit un ABI en vertu de sa propre implémentation, et d'autres (ou futures versions de lui-même) peuvent ou non choisir de garder cela cohérents. Par exemple, GCC tente de garder même le C ++ abi cohérent, tandis que MSVC de Microsoft enfreint l'ABI avec chaque libération. Pour C, il est un peu plus facile, car tout ABI est relativement petit et la majeure partie est déterminée par le matériel. Pour autant que je sache, la fonction Les conventions appelantes sont la seule chose importante à spécifier sur x86.


Seriez-vous prêt à ré-formuler les pensées des commentaires comme un addendum à votre réponse? Ils représentent le Coloseste à ma réponse souhaitée de toutes les informations ici.


Merci. C'est exactement l'info que je cherchais.