Une implémentation compatible C ANSI peut-elle inclure des fonctions supplémentaires dans sa bibliothèque standard?

Une implémentation conforme à la norme ANSI C est-elle autorisée à inclure des types et des fonctions supplémentaires dans sa bibliothèque standard, autres que ceux énumérés par la norme? (Une réponse idéale ferait référence à la partie pertinente de la norme ANSI.)

Je le demande tout particulièrement parce que Mac OS 10.7 déclare la fonction getline dans stdio.h, même lors de la compilation avec gcc ou clang avec le drapeau -ansi . Cela casse plusieurs programmes plus anciens qui définissent leur propre fonction getline . Est-ce une faute de Mac OS 10.7? (La page de getline de getline sur Mac OS 10.7 indique que getline est conforme à la norme POSIX.1, getline en 2008.)

Edit: Pour clarifier, je trouve étrange que l’inclusion de stdio.h dans un programme ANSI C89 sous Mac OS 10.7 entraîne également la déclaration de la fonction getline , puisque getline n’est pas l’une des fonctions énumérées dans K & R (et vraisemblablement ANSI). description de stdio.h. En particulier, essayer de comstackr noweb :

 gcc -ansi -pedantic -c -o notangle.o notangle.c In file included from notangle.nw:28: getline.h:4: error: conflicting types for 'getline' /usr/include/stdio.h:449: error: previous declaration of 'getline' was here 

Est-ce un bogue dans Mac OS 10.7 incluant la déclaration de getline dans stdio.h même lors de la compilation pour la norme ANSI C89?

De la section 7.1.3, paragraphe 2 de n1570 (qui est un brouillon de C1x):

Aucun autre identifiant n’est réservé.

Ceci est la partie qui signifie que getline ne devrait pas être défini par le , car ce n’est pas un identifiant réservé selon la spécification. Donc, si votre bibliothèque définit getline dans , elle n’est pas techniquement conforme à la norme C …

Cependant, vous devriez pouvoir utiliser les macros de test de fonctionnalité pour que getline soit pas défini dans .

 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L #include  

Cela vous donnera uniquement les définitions des anciennes normes POSIX. Cela ne fonctionnera pas avec certaines implémentations de GNU C ++, ce qui est EXTREMEMENT fruSTRANT pour certains.

La section pertinente de la page de manuel est (extraite d’une page de manuel de glibc, désolé …)

    Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros (7)):

        getline (), getdelim ():
            Depuis glibc 2.10:
                _POSIX_C_SOURCE> = 200809L ||  _XOPEN_SOURCE> = 700
            Avant la glibc 2.10:
                _GNU_SOURCE

Cette partie de la page de manuel vous indique quelles macros doivent être définies pour quelles valeurs afin d’obtenir la définition. Mon pari est que _POSIX_C_SOURCE est déjà défini par votre compilateur à 200809L .

L’idée des macros de test de fonctionnalité est que, si vous définissez vos macros, telles que _POSIX_C_SOURCE , _BSD_SOURCE , _XOPEN_SOURCE , etc., vous n’aurez pas à vous inquiéter des nouvelles fonctions de bibliothèque en conflit avec vos fonctions existantes. Il y a aussi _GNU_SOURCE , qui allume tout si vous utilisez glibc, mais je suggère de donner une large _GNU_SOURCE cette macro.

Oui, une implémentation conforme est autorisée à définir des identifiants supplémentaires, y compris des fonctions, à condition qu’ils fassent partie des identifiants réservés de la norme. Par exemple:

  • Tous les identificateurs commençant par un trait de soulignement et une lettre majuscule ou un autre trait de soulignement sont toujours réservés pour toute utilisation.

  • Tous les identificateurs commençant par un trait de soulignement sont toujours réservés à une utilisation en tant qu’identificateurs avec une étendue de fichier dans les espaces de nom de balise et ordinaire;

  • Tous les noms externes commençant par, is , to , str , mem ou wcs suivis d’une lettre minuscule;

De plus, certains noms ne sont réservés que si vous incluez certains en-têtes. Par exemple, si vous incluez vous pouvez définir n’importe quelle macro commençant par E suivie d’un chiffre ou d’une lettre majuscule.

Cependant, getline() n’est pas un nom réservé, et une implémentation conforme doit le rendre disponible pour le propre usage du programmeur.