2009-07-22 8 views
2

J'ai une erreur de compilation sur le code suivant:Le tableau C char n'est pas un modèle de chaîne?

printf (tampon (char *));

et le message d'erreur que je reçois est:

CC1: Format pas une chaîne littérale et aucun argument de format ...

Je soupçonne qu'il ya des bibliothèques que j'ai oublié d'installer, comme je pouvais compiler et exécuter le code sans erreur sur l'autre machine ...

PS: La question se pose avec le fait que j'étais capable d'exécuter le même code sur une autre machine ... Je soupçonne une différence dans la version gcc pourrait causer un problème comme celui-ci?

+0

Le texte semble très similaire à un avertissement et non à une erreur. Pouvez-vous donner plus d'informations sur le compilateur que vous utilisez et quelles sont les options que vous utilisez? –

+0

poster la définition de 'buffer' –

+0

Ma mémoire est un peu floue à ce sujet, mais il est souvent possible de promouvoir les avertissements aux erreurs. –

Répondre

5

Les nouvelles versions de GCC essayent d'analyser la chaîne de format passée à printf et aux fonctions similaires et de déterminer si la liste d'arguments correspond correctement à la chaîne de format. Il ne peut pas faire cela parce que vous lui avez passé un tampon pour le premier argument, qui serait normalement une chaîne de format.

Votre code n'est pas incorrect C, c'est juste une mauvaise utilisation de C. Comme d'autres mentionné, vous devriez utiliser "% s" comme une chaîne de format pour imprimer une seule chaîne. Cela vous protège d'une classe d'erreurs qui impliquent des signes de pourcentage dans votre chaîne, si vous ne contrôlez pas l'entrée. Il est recommandé de ne jamais transmettre autre chose qu'un littéral de chaîne comme premier argument de la famille de fonctions printf ou sprintf.

+0

très bien, réponse claire –

+0

Je pense que vous avez cloué le problème :) – Lawrence

4

essayer

printf ("% s", (char *) tampon);

;-)

+0

La question se pose avec le fait que j'étais capable d'exécuter le même code sur une autre machine ... Je soupçonne une différence dans la version gcc pourrait causer un problème comme celui-ci? – Lawrence

+0

eh bien, il semble que cette autre machine ne soit pas standard C – tkotitan

+0

printf (% s) est une mauvaise pratique car vous risquez de détruire la pile si votre chaîne contient des caractères spéciaux (% d,% s, etc.). Le premier argument de printf devrait toujours être un littéral de chaîne. Je suppose que les différentes versions de GCC sont plus strictes quant à savoir si elles vous permettent ou non de le faire. – Falaina

0

Ceci est un avertissement pour votre sécurité, pas une erreur. Ce nouveau compilateur semble être plus strict à ce sujet. Je ne pense pas que c'est illégale en C, donc le compilateur devrait avoir une option pour désactiver le traitement comme une erreur.

Toutefois, vous ne voulez pratiquement jamais transmettre autre chose qu'un littéral de chaîne comme premier argument à printf. La raison pour laquelle cela est si horrible est que le compilateur a une vérification intégrée spéciale pour vous en avertir: Supposons que la chaîne non littérale que vous transmettez comme premier argument à printf contienne des caractères de formatage printf. printf va alors essayer d'accéder aux deuxième, troisième, quatrième, etc, arguments que vous n'avez pas réellement transmis, et pourrait bien planter votre programme en essayant de le faire. Si le premier argument non littéral est réellement fourni par l'utilisateur, alors le problème est encore pire car un utilisateur malveillant peut planter votre programme à volonté.

+0

Habituellement, vous pouvez faire ce que vous voulez faire avec un littéral de chaîne pour une chaîne de format, d'autant plus que le reste de l'instruction est corrigé au moment de la compilation. Il peut y avoir des cas où il est préférable de passer une chaîne non-littérale, mais comme Tyler souligne que c'est une pratique dangereuse, et vous ne devriez jamais utiliser l'entrée de l'utilisateur de cette façon. –

1

Cet avertissement est généré par gcc si

-Wformat-nonliteral 

est réglé. Il ne fait pas partie de -Wall ou -Wextra (au moins pour la version 4.4.0), il suffit de le supprimer si vous voulez que le code compile sans avertissement.

Questions connexes