-
Notifications
You must be signed in to change notification settings - Fork 967
Document exceptions to the rules for parsing C arguments #2585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This description was empirically wrong, which made it rather confusing to read and rely upon.
@vtjnash : Thanks for your contribution! The author(s) have been notified to review your proposed change. |
Note that others have observed that the behavior of this undocumented rule changed in VS 2008: https://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULES |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @vtjnash. Per your request, the content has been clarified, and your example included.
@vtjnash There are several command-line parsing routines in use in Windows, and different apps use different ones. The Win32 API provides CommandLineToArgvW that behaves mostly like the C runtime startup, but may be different in some details. The C# startup uses yet another one. Documentation for one of these parsers doesn't necessarily apply to any of the others, so we won't discuss the differences. The command line that a C or C++ program sees in its First comes processing by the command processor itself, which spawns the program process. It passes an environment, which contains a copy of the interpreted command line. It may have stripped out escapes from a batch file, or coalesced multiple lines, or streamed the command line in via a pipe. You have to read the docs on your command line processor to know what it might do before it hands off a command line to a spawned process. Different command processors may do different things. And a command processor isn't the only way a process can be spawned. Your app may have been spawned by a system call from another program, and the command line you get is up to that program. Next comes processing by the runtime startup, which preps a bunch of things, including the The common command-line parsing routine used by the runtime startup code for console and Windows apps is available in source form in the Windows 10 SDK, under Your example command line, I've updated the PR to reflect the behavior. Unfortunately, I touched enough that now your agreement to the license terms is required before I can merge it. If you would be so kind, I'll take care of the rest. Thanks! [edit because I pressed Comment before finishing.] |
@corob-msft : Thanks for your contribution! The author(s) have been notified to review your proposed change. |
I think it's worth noting that this is only true for VS2008 and later. For msvcrt-based applications (such as anything compiled by mingw-w64 or mingw32 or older applications such as python before 3.3 according to https://wiki.python.org/moin/WindowsCompilers#Which_Microsoft_Visual_C.2B-.2B-_compiler_to_use_with_a_specific_Python_version_.3F) |
These documents are written to apply to VS 2015 and later, For VS 2008 and other out-of-support products, we provide access to the original docs under previous versions. Sure, it may be annoying if you're hoping for a one-stop shop for your Python 2.7 on mingw32 command-line argument parsing needs. But since 99% of readers are here for the most recent couple of versions of MSVC, we try not to slow them down with material that doesn't apply to them. |
I just fear that it's still potentially misleading, since users may refer to this expecting to learn how to correctly launch an external program, and not realize that programs compiled by an older version of MSVC (such as python) may not follow these rules. |
Just dropping back by again to record another another place in this repo I stumbled across, which had also copied the incorrect documentation from here: https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-160 |
This description was empirically wrong, which made it rather confusing to read and rely upon. This is my best guess at the actual behavior, based upon some experiments, though I'm hoping the actual behavior will be documented based upon reading of the relevant codes themselves.
Note that this incomplete description was copied to other places, including:
The
CommandLineToArgvW
function documentation also contains the misleading claim that "The GetCommandLineW function can be used to get a command line string that is suitable for use as the lpCmdLine parameter". This is not quite true, as the quoting/escape rules applied to argv[0] are usually different than those for the remaining arguments, so the user may want to first scan forward to the first space character not enclosed in double quotes.Amusingly, dotnet also contains some contradictory advice to this existing documentation, but helpfully also gives a sample program that can be used to directly test in what ways it is non-conforming: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.arguments, and this seems to have lead to this other very long conversation about the many ways that this can and has caused problems: PowerShell/PowerShell#1995