{"action":"opened","issue":{"url":"https://api.github.com/repos/conda/conda-build/issues/2524","repository_url":"https://api.github.com/repos/conda/conda-build","labels_url":"https://api.github.com/repos/conda/conda-build/issues/2524/labels{/name}","comments_url":"https://api.github.com/repos/conda/conda-build/issues/2524/comments","events_url":"https://api.github.com/repos/conda/conda-build/issues/2524/events","html_url":"https://github.com/conda/conda-build/issues/2524","id":276977197,"number":2524,"title":"Length of optimized c++ strings does not change when prefix is replaced","user":{"login":"Zaharid","id":5675858,"avatar_url":"https://avatars2.githubusercontent.com/u/5675858?v=4","gravatar_id":"","url":"https://api.github.com/users/Zaharid","html_url":"https://github.com/Zaharid","followers_url":"https://api.github.com/users/Zaharid/followers","following_url":"https://api.github.com/users/Zaharid/following{/other_user}","gists_url":"https://api.github.com/users/Zaharid/gists{/gist_id}","starred_url":"https://api.github.com/users/Zaharid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Zaharid/subscriptions","organizations_url":"https://api.github.com/users/Zaharid/orgs","repos_url":"https://api.github.com/users/Zaharid/repos","events_url":"https://api.github.com/users/Zaharid/events{/privacy}","received_events_url":"https://api.github.com/users/Zaharid/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-11-27T10:58:42Z","updated_at":"2017-11-27T10:58:42Z","closed_at":null,"author_association":"NONE","body":"Consider a piece of C++11 code like:\r\n\r\n```c++\r\nstd::string get_profile_path() {\r\n  char *env_path = std::getenv(\"NNPDF_PROFILE_PATH\");\r\n  if (env_path) {\r\n    return env_path;\r\n  }\r\n  auto p = DEFAULT_NNPDF_PROFILE_PATH;\r\n  return p;\r\n}\r\n```\r\n\r\nwhere `DEFAULT_NNPDF_PROFILE_PATH` is some compile time constant that contains the `conda` prefix, and we hope to have replaced for the corresponding environment prefix.\r\n\r\nThis works, and the substitution indeed happens. However users end up seeing a path like:\r\n```\r\n'/Users/user/miniconda3/share/NNPDF/nnprofile.yaml\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\r\n```\r\nwith all the zeros. The reason is that an optimizing compiler may decide to build the `std::string` object at compile time and set its length to the length of the \"placeholder\" prefix, while not bothering to recompute it at runtime, from the position of the first \\0. This then breaks in all sorts of ways (e.g. python raises an exception if \\0s are passed as paths). The solution is to make a variable volatile:\r\n```c++\r\nstd::string get_profile_path() {\r\n  char *env_path = std::getenv(\"NNPDF_PROFILE_PATH\");\r\n  if (env_path) {\r\n    return env_path;\r\n  }\r\n  volatile auto p = DEFAULT_NNPDF_PROFILE_PATH;\r\n  return p;\r\n}\r\n```\r\nto force the compiler to skip the optimization for that code.\r\n\r\nI don't know if there is a better way of doing this. In particular it requires patching third party code. See:\r\nhttps://github.com/Zaharid/conda-recipes/commit/c17240a157c50bb661622c6eca488db422b93108\r\n\r\nI have seen this problem with both gcc on linux and clang on mac, when sufficiently recent versions are used.\r\n\r\n"}}
{"actor":{"display_login":"Zaharid"}}