{"action":"opened","issue":{"url":"https://api.github.com/repos/ros2/rcl/issues/219","repository_url":"https://api.github.com/repos/ros2/rcl","labels_url":"https://api.github.com/repos/ros2/rcl/issues/219/labels{/name}","comments_url":"https://api.github.com/repos/ros2/rcl/issues/219/comments","events_url":"https://api.github.com/repos/ros2/rcl/issues/219/events","html_url":"https://github.com/ros2/rcl/issues/219","id":305381921,"number":219,"title":"handling of command line arguments","user":{"login":"wjwwood","id":100427,"avatar_url":"https://avatars1.githubusercontent.com/u/100427?v=4","gravatar_id":"","url":"https://api.github.com/users/wjwwood","html_url":"https://github.com/wjwwood","followers_url":"https://api.github.com/users/wjwwood/followers","following_url":"https://api.github.com/users/wjwwood/following{/other_user}","gists_url":"https://api.github.com/users/wjwwood/gists{/gist_id}","starred_url":"https://api.github.com/users/wjwwood/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wjwwood/subscriptions","organizations_url":"https://api.github.com/users/wjwwood/orgs","repos_url":"https://api.github.com/users/wjwwood/repos","events_url":"https://api.github.com/users/wjwwood/events{/privacy}","received_events_url":"https://api.github.com/users/wjwwood/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-03-15T01:12:28Z","updated_at":"2018-03-15T01:12:28Z","closed_at":null,"author_association":"OWNER","body":"In ROS 1, command line arguments specific to ROS were removed, see:\r\n\r\n> argc and argv\r\n> ROS uses these to parse remapping arguments from the command line. It also modifies them so that they no longer contain any remapping arguments, so that if you call ros::init() before processing your command line you will not need to skip those arguments yourself.\r\n\r\n-- https://wiki.ros.org/roscpp/Overview/Initialization%20and%20Shutdown#Initializing_the_roscpp_Node\r\n\r\nAnd the signature for `roscpp::init()` uses `int & argc, char ** argv`, allowing it technically to modify what ever C array of strings you give it. This is permissible according to my research, e.g.:\r\n\r\n> > The strings are modifiable, although these modifications do not propagate back to the execution environment: they can be used, for example, with std::strtok. The size of the array pointed to by argv is at least argc+1, and the last element, argv[argc], is guaranteed to be a null pointer.\r\n\r\n-- http://en.cppreference.com/w/cpp/language/main_function\r\n\r\nBut modifying the system provided `argv` automatically (implicitly) is a bit surprising for users.\r\n\r\nOther places recommend `int main(int argc, char const * argv[])` as the signature to main, which I can't find a foundation for, but seems like a reasonable thing to do.\r\n\r\n----\r\n\r\nFor ROS 2, I'd like to propose that we change our `rcl` interface and down to not directly modify `argv`, and instead provide a function that removes the arguments by returning a copy that is pruned (still not modifying the originals). In `rclcpp` we can do something like have `rclcpp::init()` return a `vector<string>` rather than mutate the `argc` and `argv` it was given. Which keeps the number of statements low, but again avoids mutating the arguments in place.\r\n\r\nSo that would mean:\r\n\r\n- [ ] `void init(int argc, char * argv[])` -> `void init(int argc, char const * const argv[])`\r\n  - https://github.com/ros2/rclcpp/blob/168d75cf1ec29ac92ce0e1dfc224c6db96b67167/rclcpp/include/rclcpp/utilities.hpp#L55-L56\r\n- [ ] `rcl_ret_t rcl_init(int argc, char ** argv, rcl_allocator_t allocator)` -> `rcl_ret_t rcl_init(int argc, char const * const argv[], rcl_allocator_t allocator)`\r\n  - https://github.com/ros2/rcl/blob/beee7c22ee2bf77c9dfd355ac51a4687109ac986/rcl/include/rcl/rcl.h#L123-L124\r\n- [ ] add function to `rcl` like `rcl_ret_t rcl_remove_ros_arguments(int argc, char const * const argv[], size_t pruned_argc, char const * pruned_argv[], const rcl_cli_arguments_t * parsed_arguments)`\r\n  - note `rcl_cli_arguments_t` is created after calling `rcl_parse_arguments`, which `rcl_init` does\r\n  - this is dependent on https://github.com/ros2/rcl/pull/217\r\n- [ ] add C++ version of `rcl_remove_ros_arguments`, e.g. `vector<string> rclcpp::remove_ros_arguments(int argc, char const * const argv[], const rcl_cli_arguments_t * parsed_arguments)` or something like that\r\n- [ ] add convenience version of `rclcpp::init` which removes the args and exposed the pruned args automatically, e.g. `vector<string> rclcpp::init_and_remove_ros_arguments(int argc, char const * const argv[])` or something like that\r\n- [ ] add a similar behavior for `rclpy`, not sure off hand how this should look\r\n\r\n----\r\n\r\nOptionally there are few things we could do at the same time:\r\n\r\n- add support for command line arguments to `rmw_init`, it would need to:\r\n  - take `argc` and `argv` and\r\n  - have a way to indicate which indices in `argv` were \"consumed\" by the middleware and should/could be remove for the user\r\n- make all the global init functions not global, by returning a handle or structure\r\n  - this would just be good to do, and while we're touching these functions anyways...\r\n  - this would also allow us to simplify the `remove_ros_args` like functions in a few cases, especially in C++\r\n- perhaps other things I'll think of later..."}}
{"actor":{"display_login":"wjwwood"}}