2010-07-08 6 views
1

Le programme suivant est-il un programme C valide?Case d'angle de bibliothèque standard C

#include <stdio.h> 

int main() 
{ 
    fwrite("x", 1, 1, stderr); 
    fflush(stderr); 
    fgetc(stderr); 
    fwrite("y", 1, 1, stderr); 
    return 0; 
} 

Notez que j'essaie de lire depuis stderr.

Quand je compile dans Visual C++ 2008, et l'exécuter, je reçois la sortie suivante:

xy 

ce qui est logique. Toutefois, lorsque je redirige stderr vers un fichier (test.exe 2> foo.txt), j'obtiens une fenêtre "Échec de l'assertion de débogage" avec le message suivant: "Comptage de flux incohérent: vidage entre lecture et écriture consécutives". L'ajout d'un fflush entre la lecture et l'écriture résout le problème. (Cela se produit dans la version de débogage Dans les versions de version, la deuxième écriture échoue silencieusement).

Ce comportement est-il correct ou s'agit-il d'un bogue de la bibliothèque du ? Je ne pouvais pas trouver nulle part aucune règle décrivant quand lecture ou d'écriture sont illégales en C.

+4

La lecture d'un flux de sortie est un comportement indéfini. Et que diable voulez-vous qu'il fasse? –

+1

On note que ce ne serait pas un bogue de compilateur mais un bogue d'implémentation de bibliothèque. –

+1

@NeilButterworth - Je ne crois pas que la lecture d'un flux de sortie devrait provoquer UB. Selon l'Opengroup, cela devrait simplement faire échouer 'fgetc' et mettre errno dans' EBADF' (voir http://www.opengroup.org/onlinepubs/009695399/functions/fgetc.html) –

Répondre

3

C99 dit dans 7.19.5.3 (fopen), paragraphe 6:

Lorsqu'un fichier est ouvert avec le mode de mise à jour ('+' en tant que second ou troisième caractère dans la liste ci-dessus des valeurs d'argument mode), l'entrée et la sortie peuvent être effectuées sur le flux associé. Toutefois, la sortie ne doit pas être suivie directement par une entrée sans appel à la fonction fflush, [...] et l'entrée ne doit pas être suivie directement par la sortie sans appel intermédiaire à une fonction de positionnement de fichier, sauf si l'opération de saisie rencontre une fin. de-fichier.

Félicitations pour avoir découvert ce boîtier de coin en pratique. L'implémentation de la bibliothèque est complètement correcte, puisque vous violez le doit cité ci-dessus. En passant, il n'est pas rare de lire stderr. Ceci est utile lorsque stdin et stdout sont redirigés et qu'aucun terminal n'est disponible. Bien que C99 ne garantisse pas qu'il soit lisible, je me souviens de certains cas sur des systèmes similaires à POSIX où cela avait été fait.

+0

Je ne vois pas comment cela répond à la question du tout. –

+0

Il répond à la question 99%.Théoriquement, la clause "à moins" à la fin peut impliquer qu'une lecture ratée ne compte pas, mais je ne pense pas que quiconque ait pensé à ce cas, donc c'est indéfini. – Amnon

+0

@Amnon On dit "Quand un fichier est ouvert avec le mode de mise à jour" - qu'est-ce qui vous fait penser que stderr est ouvert dans ce mode? Et vous ne pouvez pas appeler les fonctions de positionnement sur stderr. –

Questions connexes