main ohne __stdcall
-
Warum kann man eigentlich bei der main() Funktion das __stdcall davor weglassen?
Müsste man nicht richtiger Weise so schreiben:int __stdcall main()
?
Behandelt der Linker die gewöhnliche main() - Funktion trotzdem so, als stünde __stdcall davor ?
-
ANSI C kennt kein __stdcall, keine Ahnung, was das sein soll.
Es gibt nur 3 Signaturen, die von ANSI C unterstützt werden:
int main(void); int main(int argc, char *argv[]); int main(int argc, char **argv);
Alle andere entsprechen nicht dem Standard.
-
Rein theoretisch ruft doch eigentlich die C-Runtime-DLL 'meine' main()-Funktion auf? Und je nach OS müsste doch die Einstiegs-Funktion meines Programms mal ohne __stdcall (alles außer Windows), ein andermal unbedingt mit __stdcall (Eigenheit von Windows) definiert werden.
Deshalb frage ich ja, ob der Visual C Compiler da (implizit) meine (Standard-C) main() als __stdcall main() interpretiert? Oder ist das der C-Runtime-DLL egal, ob die Einstiegs-Funktion meines Programms __stdcall main() oder __cdecl main() heißt?
mfg
-
StdCall schrieb:
Warum kann man eigentlich bei der main() Funktion das __stdcall davor weglassen?
Müsste man nicht richtiger Weise so schreiben:int __stdcall main()
?
Behandelt der Linker die gewöhnliche main() - Funktion trotzdem so, als stünde __stdcall davor ?Würd mich eher interessieren, wo man das hinschreiben kann.
Wenn du wissen willst, warum int main() reicht: Default verwendet der Compiler die C-Aufrufkonvention.StdCall schrieb:
Rein theoretisch ruft doch eigentlich die C-Runtime-DLL 'meine' main()-Funktion auf?
Weder theoretisch, noch praktisch weiß dein Rechner was ein "DLL" sein soll.
-
Dieser Thread wurde von Moderator/in rüdiger aus dem Forum ANSI C in das Forum Compiler- und IDE-Forum verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Man sollte mit diesen Konstrukten auch nicht einfach so rumspielen, da damit die Aufrufkonvention geändert wird. Das kann zu mysteriösen Fehlern führen. Insbesondere da die Aufrufkonvention in C imho nicht __stdcall, sondern __cdecl ist (Microsoft Visual Studio).
-
main ist eine c methode und hat somit die __cdecl Aufrufkonvention. Du kannst es __cdecl deshalb weglassen, da es default ist.
Wenn Du auf die CRT verzichtest und ein Programm schreibst, was direkt vom OS angesprungen wird, dann kannst Du verwenden was Du willst
solange Du weisst, was Du machst...
http://blog.kalmbach-software.de/2008/02/02/smallest-application-size-for-win32-console-application/
-
Jochen Kalmbach schrieb:
main ist eine c methode und hat somit die __cdecl Aufrufkonvention. Du kannst es __cdecl deshalb weglassen, da es default ist.
Wenn Du auf die CRT verzichtest und ein Programm schreibst, was direkt vom OS angesprungen wird, dann kannst Du verwenden was Du willst
solange Du weisst, was Du machst...
http://blog.kalmbach-software.de/2008/02/02/smallest-application-size-for-win32-console-application/Besten Dank für diesen sehr lehrreichen Link! Ich versuche seit einiger Zeit besser zu verstehen, in welcher Relation meine C-Programme eigentlich zum OS stehen. Womöglich wird auch gar nicht die CRT-DLL in mein C-Programm 'eingebettet', sondern wahrscheinlich ist es umgekehrt ...
thx / mfg
-
Die main Funktion wird doch sowieso inlined, also ist das egal.
-
Icematix schrieb:
Die main Funktion wird doch sowieso inlined, also ist das egal.
Hä? Erklär mal...
-
So, habe mir jetzt selber eine WinMainCRTStartup Routine geschrieben, und den Linker angewiesen, außer mit kernel32.lib alle Standardbibliotheken und insbesondere die msvcrt.lib nicht zu verwenden, keine Manifeste einzubetten usw.
Die resultierende .exe ist zwar erfreulich klein (3 kb), kann aber auch nichts Vernünftiges mehr tun.
Habe nur Sleep(10000); in der WinMainCRTStartup() Routine aufgerufen, allerdings lädt Windows 7 ja trotzdem noch zumindest die kernel32.dll in mein Programm, wodurch der Speicherverbrauch meiner (Nonsense-) exe laut Task Manager sofort wieder auf 260 KByte hochschnellt.
Was mich wundert: Im Fenster 'Prozesse' des Task-Managers gibt es noch ca. 50 weitere Prozesse, die ablaufen, aber die benötigen z.T. nur 2k Arbeitsspeicher (obwohl sie bestimmt sinnvollere Dinge tun als nur zu schlafen!).
Welche Tricks haben denn die Programmierer dieser Prozesse beim Kompilieren und Linken verwendet, damit ihre Programme nur so wenig Arbeitsspeicher benötigen?
Kommen denn diese Programme alle ohne der kernel32.dll aus ??
Oder kann man sonst noch etwas beim Kompilieren und Linken mit Visual C einstellen, damit so ein Schlaf-Programm nicht 260 kByte Arbeitsspeicher verschlingt ?
Und wenn ich gar nicht mit der kernel32.lib verlinke (was ja schuld daran ist, dass mein Programm dann zur Ladezeit sein 'eigenes' Exemplar der kernel32.dll bekommt) dann kommt ein 'Unter Windows nicht lauffähiges' Programm dabei heraus.Wie setzt man das um:
- Die .exe sollte möglichst klein sein
- Der Arbeitsspeicherverbrauch sollte nicht 260 kByte (sondern so wie die 49 anderen Prozesse im Taskmanager z.B. nur 2 kByte) ausmachen.Hoffentlich kennt sich mit dem Thema jemand aus.
Thx für Tipps.
-
Jochen Kalmbach schrieb:
Icematix schrieb:
Die main Funktion wird doch sowieso inlined, also ist das egal.
Hä? Erklär mal...
Ich denke er meint einfach, dass zu Programmbeginn kein expliziter call von main stattfindet, sondern der Programm Code direkt ausgeführt wird.
Das ist erstens nicht ganz richtig und zweitens soll sich das "egal" wohl auf die Aufrufkonvention beziehen. Da diese jedoch vorrangig angibt, wie die Parameter übergeben werden, ist dies keinesfalls egal, da sonst die Funktion schlecht wissen kann, wo sie ihre Argumente herbekommt.
-
StdCall schrieb:
Was mich wundert: Im Fenster 'Prozesse' des Task-Managers gibt es noch ca. 50 weitere Prozesse, die ablaufen, aber die benötigen z.T. nur 2k Arbeitsspeicher (obwohl sie bestimmt sinnvollere Dinge tun als nur zu schlafen!).
Was lässt Du Dir denn da anzeigen? Du musst "Privater Speicher" anschauen...
Ich vermute, dass Du Dir das Working-Set anschaust... das wird bei Deiner Anwendung auch kleiner, wenn Du sie minimierst...StdCall schrieb:
Oder kann man sonst noch etwas beim Kompilieren und Linken mit Visual C einstellen, damit so ein Schlaf-Programm nicht 260 kByte Arbeitsspeicher verschlingt ?
Nein. Der Speicherverbrauch ist von der kernel32.dll und ntdll.dll. Dieser lässt sich nicht reduzieren.
StdCall schrieb:
(was ja schuld daran ist, dass mein Programm dann zur Ladezeit sein 'eigenes' Exemplar der kernel32.dll bekommt)
Nein, die kernel32.dll wird als sog. "Shared DLL" geladen. D.h. der Code wird in allen Prozessen nur einmal geladen, die Daten werden aber in *jedem* Prozess neu allokiert! Und das sind eben die Daten die diesen Speicher benötigen.
Das kannst Du auch anschauen indem Du Deinen Prozess mal mit WinDbg anschaust...
-
Stimmt, das wird im Task-Manager (Windows 7) vermutlich nicht ganz korrekt dargestellt, beim Resourcen-Monitor stehen unter 'Privat' ganz andere (und plausiblere) Zahlen.
Also speichersparender als mindestens mit der kernel32.dll zu verlinken (== mindestens ~260 kByte privater Speicher) ist für einen Windows 7 - Prozess scheinbar tatsächlich nicht möglich, schafft auch keiner der 50 anderen Prozesse. (Ausnahme: Prozess 'System')
Thx für die vielen Ratschläge, sehe jetzt die Dinge etwas klarer