Initialiser des variables avec Stdout et stderr - C - Programmation
Marsh Posté le 10-11-2005 à 22:54:39
Comme tu l'as noté, il n'est pas possible de changer FILE * en const, donc il n'est pas possible de faire FILE *err_file = stderr; parce que cela transformerait stderr en quelque chose de non constant, ce qui n'est pas permis.
Par ailleurs, cela ne me parait pas une bonne idée de vouloir masquer stdout et stderr en les renommant, car cela rendra la lecture de tes programmes plus difficiles pour celui qui, plus tard, fera la maintenance de tes programmes.
Cela dit, si tu veux vraiment renommer stdout et stderr, alors tu peux utiliser
#define |
.
Marsh Posté le 10-11-2005 à 23:11:02
Ba en fait c pas mon programme, j'essais juste de le recompiler. Mais apparemment, FILE *err_file = stderr marchait pour la personne qui fait le programme ? Enfin bref, si comme tu dis c pas possible, alors je mettrais directement stderr et stdout.
Merci pour ta réponse
++
Marsh Posté le 11-11-2005 à 01:03:03
cervantes a écrit :
|
Non. ce sont des variables non modifiables. (Non-modifiable l-values)
Citation : |
|
Marsh Posté le 11-11-2005 à 04:16:19
En fait ce n'est pas vraiment que ce sont des variables non modifiables (elles sont modifiables, dans un bloc). C'est surtout que ce sont des variables dont la valeur n'est pas connue à la compilation. Si tu veux savoir ce qui se passe exactement, stdout et stderr sont déclarés de la façon suivante dans stdio.h :
Code :
|
Ce qui veut dire que ce les addresses des deux structures _IO_FILE en question sont définies dans un autre module (une autre unité de compilation), et ne sont pas connues au moment ou le compilateur compile ton module. Maintenant le truc qu'il faut bien comprendre, c'est que pour initialiser une variable globale, le compilateur doit absolument connaitre la valeur d'initialisation au moment ou il compile le module en question, parce que la valeur est écrite directement en dur dans le binaire. Ce n'est pas le cas ici, d'où l'erreur.
Maintenant, pourquoi ça marche en initialisant err_file et out_file dans un bloc, comme le propose Emmanuel ? Parce que pour faire ça, le compilateur n'a pas besoin de connaitre la valeur d'initialisation au moment ou il compile le module. Tout ce que le compilateur a besoin de savoir, c'est que cette valeur est définie quelque par dans un autre module (ce que lui dit le "extern" ). Dans ce cas il n'écrit pas la valeur directement dans le binaire; il génère juste un petit bout de code qui va chercher une addresse dans une zone spéciale (appelons cette zone "TOC" comme Table Of Content), puis lit la valeur à cette adresse, et l'assigne enfin à err_file. L'adresse qui se trouve dans la TOC est écrite soit par l'éditeur de lien (donc au moment du link) si tu te lie statiquement avec le module qui contient la valeur d'initialisation, soit par le loader (donc au chargement de ton programme) si tu te lie dynamiquement avec ce module (ce qui est le cas ici mais ne change rien au problème).
Edit : si tu veux un exemple minimal, le module suivant ne compile pas non plus, pour la même raison (à compiler avec -c) :
Code :
|
Marsh Posté le 11-11-2005 à 09:40:09
matafan a écrit : En fait ce n'est pas vraiment que ce sont des variables non modifiables (elles sont modifiables, dans un bloc). C'est surtout que ce sont des variables dont la valeur n'est pas connue à la compilation. |
Oui, et c'est ça le noeud du problème.
Citation :
|
Ca, c'est pour une implémentation particulière. Le langage C ne précise pas comment sont définies ces valeurs.
cygwin
|
mingw
|
Code Composer (DSP Texas Instrument)
|
Borland C
|
Diab (Power PC)
|
Visual C++
|
Pelles C
|
Marsh Posté le 11-11-2005 à 16:30:26
Je n'en demandais pas autant mais merci pour toutes ces précisions. Maintenant tout est clair et en effet ca marche tres bien en modifiant comme ci dessus.
++
Marsh Posté le 12-11-2005 à 05:20:17
Emmanuel Delahaye a écrit :
|
Hallucine je ? Mais non... je ne rève pas. Emmanuel a réellement déclaré ces variables en global.
Marsh Posté le 12-11-2005 à 09:09:32
On n'a pas le choix si on veut assigner stdin et stderr à des variables.
Par contre si c'est pour assigner des flux par défaut à un programme acceptant des noms de fichier en paramètres non obligatoires, j'aurais plutôt utilisé freopen() si les arguments sont précisés. Comme ça on utilise stdin et stderr tout le long du programme, et il n'y a pas de bidouille comme ici.
Marsh Posté le 12-11-2005 à 10:11:29
Dans mon cas, c'est pour utiliser avec fprintf() uniquement, dc j'ai pas 36 solutions vu qu'elle est déclaré comme ceci:
Code :
|
Marsh Posté le 12-11-2005 à 10:55:30
cervantes a écrit : Dans mon cas, c'est pour utiliser avec fprintf() uniquement, dc j'ai pas 36 solutions vu qu'elle est déclaré comme ceci:
|
Qu'est-ce qui empêche de faire
fprintf (stdout, "hello world\" ); |
ou
fprintf (stderr, "hello world\" ); |
Marsh Posté le 10-11-2005 à 22:18:16
Slt,
J'ai ces 2 lignes de code
en compilant avec gcc, il me dit:
stderr et stdout sont des constantes, mais si je caste ca ne change rien, et je ne peux pas mettre FILE* en const.
Comment faire pour eviter cela?
++