在 2025-8-26 03:54, Pali Rohár 写道:
It was intended as a cleanup. __main is currently using atexit hooks to execute c++ destructors but for dll builds this can be done in more clean why by explicitly calling them at process detach event without need to maintain per-dll atexit hook table and hence completely avoid atexit call inclusion into every dll library.
This might violate the C++ standard which requires destructors and exit callbacks be called in the reverse order of their completion (of a destructor of a static object, which may be either a local one or a global one with namespace scope) and registration (of an exit callback). Yes there's a requirement on the order of these unrelated things.
The interface around "__main" can be entrenched in many places, and code expecting to e.g. override the entry point and just call "__main" no longer will have working C++ constructors.That already is not working. There is lot of stuff in crtexe.c and crtdll.c which needs to be called before main / dllmain and is not in __main. If somebody wants to override the default entry point for DLL then the overwritten entry point has to call _CRT_INIT function, this is documented somewhere in MS/WinAPI and mingw-w64 has also all required init parts in _CRT_INIT function.
It's possible to build a program without those. One has to carefully avoid triggering pseudo relocation (by adding explicit `dllimport` and disabling auto import), and link against a CRT DLL. One may even choose to link against libntdllcrt instead of msvcrt or UCRT. It's at least doable.
mingw-w64 is already calling gcc's __main() function in crt startup code, so basically gcc is not required to insert manual call of this function to the main function. Moreover gcc does not insert it into wmain function (when compiling with gcc -municode), so it is already inconsistent. Also gcc for linux does not insert this __main into main, so I think it would make sense to allow produce gcc compiler which would not do it neither for windows/mingw-w64.
It's really a GCC issue but I think you can try adding `#undef INVOKE__main` in 'gcc/config/i386/cygming.h'.
An explanation of why might help as well. If there is a reason to do that, it would be easier to handle review wise if it is split to a separate commit as well, with separate arguments.{ - unsigned long nptrs = (unsigned long) (ptrdiff_t) __CTOR_LIST__[0]; + unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; unsigned long i;This change, to remove the intermediate cast, looks unrelated to the rest of the changes. Is there a good reason for why we should do that? In that case it could be a separate change. It is also possible that removing it may reintroduce warnings in some build configuration.I removed it because I though that it is not needed and that ptrdiff_t was the only reason why the new file requires to include any header file. Now when I'm thinking about it, ptrdiff_t is the wrong type at this place. It should be uintptr_t, no? In memory there is stored unsigned integer which has same width as pointer, meaning is number of members and C type of memory for that variable/array is pointer. Meaning is not difference between two pointers.
When using a GNU toolchain, `__CTOR_LIST__` is defined by the linker (in 'ld/scripttempl/pe.sc' for 32-bit targets and in 'ld/scripttempl/pep.sc' for 64-bit targets) where the first element is always `-1`.
Besides, there's no difference between `intptr_t` and `uintptr_t`; the value is truncated to `unsigned long` anyway, so the cast chain is no-op.
-- Best regards, LIU Hao
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
