so setzen Sie eine DATEI** variable stdout?
Mockup von meinem Produktions-code:
/* version 1 */
#include <stdio.h>
FILE** fout = &stdout;
int main() {
fprintf( *fout, "hello\n" );
}
Funktioniert gut unter gcc, aber angeblich nicht kompiliert unter mingw (lvalue erforderlich als unäre '&' operand).
Habe ich gesehen,Ist die Einstellung einer DATEI* gleich stdout portable?; ich verstehe, dass
/* version 2 */
#include <stdio.h>
int main() {
FILE* fout = stdout;
fprintf( fout, "hello\n" );
}
wäre durchaus gültig. Allerdings brauche ich zur Voreinstellung einer globalen variable. Leider
/* version 3 */
#include <stdio.h>
FILE* fout = stdout;
int main() {
fprintf( fout, "hello\n" );
}
nicht geeignet ist, zu ersetzen, die version 1 ist; es ist nicht selbst kompiliert unter gcc (Linie 2: element-Initialisierer ist nicht konstant).
Irgendeine Idee, wie man stdout in eine variable initialisiert wird, bevor die main() gestartet wird?
Der Stdout-stream ist bereits geöffnet! Es kann nicht sein, 2 stdout zur gleichen Zeit öffnen... ich schlage vor, vielleicht mit #define oder lassen Sie sich einfach von main starten, dann speichern Sie es in eine Globale var.. Warum vor der main startet?
Warum vor der main beginnt: als Autor einer Bibliothek, ich biete meinen Usern
Warum vor der main beginnt: als Autor einer Bibliothek, ich biete meinen Usern
struct default_settings
initialisiert wird in der Bibliothek von code, und diese sind enthalten fout=stdout
unter vielen anderen parameter-Einstellungen.InformationsquelleAutor Joachim W | 2013-08-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Linux (glibc),
stdout
ist wie folgt definiert:So, Sie können tun, was Sie brauchen.
Jedoch auf MinGW,
stdout
definiert ist, wie dies instdio.h
:Ach, das ist nicht etwas, können Sie die Adresse und, als Sie entdeckt, es ist nicht etwas, das Sie verwenden können, in einer globalen Initialisierung. 🙁
Die Wurzel des Problems ist, dass der C-standard sagt, dass diese Makros, was bedeutet, dass jede portable Programm sollten keine Annahmen machen über das, was drin ist. Also, ich fürchte, es gibt keinen einfachen Weg, um zu vermeiden, Lesen
stdout
programmgesteuert. Diese Art der Sache ist, warum viele Bibliotheken verlangen einelib_initialize()
Funktion muss aufgerufen werden, bevor irgend etwas anderes.C++ nicht erlauben Konstruktoren für Globale Variablen, und diese werden automatisch aufgerufen, bevor
main
, auch für Bibliotheken. Es ist möglich, mitgcc
, hack ein C-Programm, das gleiche zu tun, aber das ist ein böser trick und ich kann mich nicht erinnern, wie es zu tun, aus der Spitze von meinem Kopf.Ich würde nur dazu:
Dass ist nicht eine große Effizienz problem: Sie hätte zu laden
fout
sowieso, und ein Vergleich mit null ist ziemlich Billig.InformationsquelleAutor ams
Entsprechend der C-standard (7.21.1),
stdout
ist ein makro, das ein Ausdruck vom Typ "Zeiger auf FILE". Es ist nicht unbedingt eine Globale variable. Es ist nicht tragbar C seine-Adresse, - - - es funktioniert in der gcc aber nicht in mingw, als Sie sah.Verwenden Sie die zweite version Ihres code --- dies ist ein tragbares.
Dritten wäre auch OK, wenn Sie bewegt die Initialisierung von
fout
innenmain
:Diese Initialisierung kann nicht kombiniert werden mit der Erklärung der
fout
alsstdout
ist nicht (zumindest nicht notwendigerweise) ein konstanter Ausdruck.Wenn Sie möchten, um eine
FILE **
Zeiger verwenden:aber wieder die Initialisierung der
mystdout
nicht an seine Erklärung, aus dem gleichen Grund.fout
ist der TypFILE*
oderFILE**
. Was wichtig für mich ist, dass die Nutzer von "meine Bibliothek" erhalten solltenfout=stdout
standardmäßig aktiviert; Sie sollten nicht aufgefordert werden, legen Sie eine Zeile wiefout=stdout
in Ihrem code; sollte dies durch eine default-Initialisierung, bevor main() beginnt.Rechts, version 3 erfordert, dass die globalen Variablen initialisiert werden innerhalb
main
, wie ich schrieb in meiner Antwort. Ich bin Bearbeiten.Und warum gehst du nicht einfach eine Globale variable verwenden, sichtbar nach außen? Benutzer können dann schreiben Sie einfach
globalFile = some_other_file;
bequem.In der Tat, ich bin versucht, eine Globale variable verwenden; siehe meine Versionen 1 und 3. Die Frage ist, wie Sie initialisiert werden, es in meine Bibliothek, also vor der main startet.
Ich sehe zwei Optionen: 1) Sie haben könnten
initMyLibrary
Funktion. 2) könnten Sie initialisieren es mitNULL
- und re-initialisieren Sie es auf Nachfrage, wenn es zuerst verwendet wurde. Wenn beide inakzeptabel sind, starten Sie eine Frage zur Bibliothek der Initialisierung, dies ist ein Allgemeines problem. Das Problem hier ist, dassstdout
ist nicht (unbedingt) bekannt, die zur compile - /link-Zeit.InformationsquelleAutor nickie
Ich glaube nicht, dass dies eine sehr gute Idee, da die Datei-Deskriptoren sind in der Regel nicht tragbar. Es macht auch die Implementierung von library-Funktionen ziemlich low-level, oder du wirst eine harte Zeit haben, synchronisieren von Datei-Deskriptoren
FILE
Zeiger.Allerdings, wie @JoachimWuttke explizit danach gefragt, hier ist, was ich im Sinn hatte, in meinem früheren Kommentar:
fprintf
ersetzt durchwrite
. Ich fürchte, ich bin nicht bereit, diesen Preis zu zahlen. Also ich meine die Einsicht, dass es keine einfache und saubere Lösung.InformationsquelleAutor nickie