C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::argc std::argv (available to global constructors)

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Tue, 13 Jun 2023 16:23:21 +0200
Perhaps also applicable   P1275R0 Desert Sessions: Improving hostile environment interactions https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1275r0.html   https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1750r1.pdf P1750R1 A Proposal to Add Process Management to the C++ Standard Library     -----Ursprüngliche Nachricht----- Von:Tom Honermann via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Di 13.06.2023 13:41 Betreff:Re: [std-proposals] std::argc std::argv (available to global constructors) An:std-proposals_at_[hidden]; CC:Tom Honermann <tom_at_[hidden]>; This is being pursued as WG14 N2948 (Accessing the command line arguments outside of main()). Tom. On 6/13/23 7:02 AM, Frederick Virchanza Gotham via Std-Proposals wrote: [ I tried to put this up on GodBolt and provide a link, but I gave up on the GNU inline assembler syntax, I just couldn't get it to work ] Ever since C++ came out in 1979, there hasn't been any good reason why the command line arguments to a program cannot be used as arguments to the constructors of global objects. I propose that in <cstdlib>, there will be: namespace std { extern int argc; extern char **argv; } To implement this in my following example, the entry point to the program will be 'entrypoint' instead of '_start', and the values of 'argc' and 'argv' will be gotten from the stack. The following syntax is for the 'nasm' assembler: extern _ZSt4argc ; mangled name of std::argc (dword = 4 bytes) extern _ZSt4argv ; mangled name of std::argv (qword = 8 bytes) extern _start section .text global entrypoint:function entrypoint: push r15 ; callee-saved (we will restore it later) add rsp, 8 ; move the stack pointer to argc mov r15d, dword[rsp] mov dword[_ZSt4argc], r15d add rsp, 8 ; move the stack pointer to argv mov r15, rsp mov qword[_ZSt4argv], r15 sub rsp, 16 ; move the stack pointer back to where we stored r15 pop r15 ; restore the original value of r15 (callee-saved) jmp _start So you compile this assembler as follows: nasm -o entrypoint.o -f elf64 entrypoint.asm And then we build our program with: g++ -o prog main.cpp -no-pie entrypoint.o -e entrypoint Here's an example program that works: #include <iostream> namespace std { int argc; char **argv; } class LaserController { int const grade; char model[16u]; public: LaserController(int const arg_grade, char const *const arg_model) : grade(arg_grade) { if ( nullptr == arg_model ) { model[0u] = '\0'; return; } for ( unsigned i = 0u; i < sizeof(model); ++i ) { model[i] = arg_model[i]; if ( '\0' == model[i] ) break; } model[sizeof(model) - 1u] = '\0'; } void Print(void) { std::cout << "Grade: " << grade << ", Model: " << model << std::endl; } }; LaserController gLaser( std::argc, std::argv[ std::argc - 1u ] ); int main(int argc, char **argv) { gLaser.Print(); } -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals  

Received on 2023-06-13 14:23:23