J’essaie de comstackr un programme C sur un système Linux. J’ai une déclaration #include
pour stdlib.h
.
Lorsque je comstack le programme avec gcc
comme suit:
gcc -std=c99 -g -o progfoo progfoo.c progbar.c
Je reçois des avertissements sur la Implicit declaration of function [srand48, drand48, bzero, or close]
.
Comstackr à la place en tant que:
gcc -g -o progfoo progfoo.c progbar.c
ne me donne pas les avertissements, mais il crie à propos de mon utilisation de boucles for
(ce qui était la raison pour laquelle -std=c99
).
Étant donné que man srand48
mentionne notamment , ce que j’ai, je ne suis pas certain de savoir quel autre problème pourrait être. Les boucles
for
ne sont pas essentielles à tout (elles étaient juste pour gagner du temps lors de l’initialisation d’un tableau) donc je n’ai aucun problème à les supprimer, mais avant je voudrais confirmer si le standard c99
remplace certains aspects de mon #include
déclarations.
J’utilise gcc 4.1.2-50 (Red Hat)
.
Est-ce que -std = c99 peut empêcher mes #includes de fonctionner correctement?
Non, mais ils peuvent montrer des limites dans votre connaissance de leur fonctionnement 🙂
Alors que les fonctions [sd]rand48
ont un prototype dans stdlib.h
, elles sont dans un #ifdef
, au moins sur mon système:
#if defined __USE_SVID || defined __USE_XOPEN
Vous devrez donc probablement définir explicitement l’une de ces macros.
Cependant, avant de l’essayer, sachez que cela ne fonctionne pas. C’est parce que tout cela est contrôlé avec les macros de test de fonctionnalités de gcc
.
Il existe un ensemble très compliqué de règles utilisées pour activer ou désactiver des fonctionnalités spécifiques dans features.h
et les macros créées contrôlent ce que les fichiers d’en-tête incluent et excluent. Les variantes __USE_*
sont effacées et définies dans ce fichier d’en-tête en fonction des autres macros fournies par vous.
Par exemple, pour que __USE_SVID
défini afin que vous puissiez utiliser srand48
, vous devez fournir le compilateur avec un paramètre -D_SVID_SOURCE
.
Mais peut-être que le moyen le plus simple consiste à utiliser simplement C99 avec les extensions GNU. Pour ce faire, remplacez -std=c99
par -std=gnu99
.
Et, pour bzero
et close
, ceux-ci peuvent être obtenus à partir de ssortingngs.h
et unistd.h
respectivement.
J’étais un peu confus au début de savoir pourquoi ceux-ci compilés avec -std=c99
quand ils n’ont absolument rien à voir avec C99 mais j’ai alors réalisé que le drapeau ne contrôle que ce que les en -têtes standard C vous donnent.
Ni ssortingngs.h
(notez le nom pluriel, ce n’est pas ssortingng.h
) ni unistd.h
font partie de ISO C.
On dirait que les fonctions que vous utilisez ne sont pas ISO C99, donc quand vous demandez une conformité ssortingcte à C99, elles ne seront pas visibles.
Informations ici: https://bugzilla.redhat.com/show_bug.cgi?id=130815
Le drapeau -D_POSIX_C_SOURCE=200809L
devrait fonctionner.
Voir aussi cette question: Pourquoi gcc ne peut-il pas trouver l’interface random () lorsque -std = c99 est défini?
L’erreur que vous obtenez fait que les fonctions que vous utilisez ne sont pas déclarées. Êtes-vous sûr d’inclure les en-têtes corrects pour eux?
De même, l’utilisation de -std=c99
peut désactiver certaines extensions qui ne font pas partie de la norme. Aucune des fonctions que vous avez mentionnées ne fait partie de la norme C. Si vous ne parvenez pas à trouver des en-têtes séparés, vous pouvez essayer -std=gnu99
.
-std=c99
fait en sorte que les en-têtes omettent tout ce qui pourrait entrer en conflit avec les utilisations de noms en dehors de l’espace de noms réservé C99, y compris toutes les fonctions POSIX standard. Le moyen portable de demander aux en-têtes de vous donner les interfaces POSIX est de définir _POSIX_C_SOURCE
sur une valeur correspondant à la version POSIX souhaitée. Pour le dernier POSIX (2008), cela signifie:
#define _POSIX_C_SOURCE 200809L
ou sur la ligne de commande:
-D_POSIX_C_SOURCE=200809L
Edit: Il semble que les fonctions que vous voulez ne soient pas dans la base POSIX mais dans l’option XSI, vous devez donc définir _XOPEN_SOURCE
sur une valeur appropriée ( 700
étant la dernière) pour les obtenir. Cela peut également être fait à partir de la ligne de commande ou de vos fichiers sources (mais si vous utilisez les fichiers source, vous devez le faire avant d’ inclure les en-têtes du système).
Les déclarations implicites (où une fonction non déclarée est supposée renvoyer int) ne sont plus autorisées dans C99.
Cela dit, gcc n’abandonnera pas la compilation.
Essayez d’inclure ssortingngs.h
pour bzero
, voir aussi la réponse de paxdiablo.
Vous demandez la conformité aux normes et C99 ne définit pas srand48()
comme une fonction fournie par
.
Pour la bibliothèque GNU C, vous pouvez demander des fonctionnalités supplémentaires en définissant une ou plusieurs des options répertoriées dans le commentaire en haut de /usr/include/features.h
, soit par #define
avant que #include
, soit par l’ /usr/include/features.h
-D
à gcc
.
Pour srand48()
(et drand48()
), vous souhaiterez probablement utiliser -D_XOPEN_SOURCE=500
ou -D_SVID_SOURCE
(ou #define _XOPEN_SOURCE 500
etc. dans les fichiers source).
bzero()
et close()
devraient fonctionner même avec -std=c99
si vous -std=c99
les fichiers d’en-tête documentés, à savoir
et
respectivement.