{"action":"created","comment":{"url":"https://api.github.com/repos/jfbastien/papers/pulls/comments/166772228","pull_request_review_id":94885695,"id":166772228,"diff_hunk":"@@ -0,0 +1,141 @@\n+<pre class='metadata'>\n+Title: Offsetof for Pointers to Members\n+Shortname: Doffsetof\n+Revision: 1\n+Audience: SG1, EWG, CWG\n+Status: D\n+Group: WG21\n+Editor: Eddie Kohler, Harvard, kohler@seas.harvard.edu\n+URL: http://wg21.link/Doffsetofr1\n+Abstract: The `offsetof` macro should support pointers to members.\n+Markup Shorthands: markdown yes\n+</pre>\n+\n+The `offsetof` macro, inherited from C and applicable to standard-layout\n+classes (and, conditionally, other classes) in C++, calculates the layout\n+offset of a member within a class. `offsetof` is useful for calculating an\n+object pointer given a pointer to one of its members:\n+\n+<xmp>\n+\n+struct link {\n+  ...\n+};\n+\n+struct container {\n+  link l;\n+};\n+\n+container* container_from_link(link* x) {\n+  // x is known to be the .l part of some container\n+  uintptr_t x_address = reinterpret_cast<uintptr_t>(x);\n+  size_t l_offset = offsetof(container, l);\n+  return reinterpret_cast<container*>(x_address - l_offset);\n+}\n+\n+</xmp>\n+\n+This pattern is used in several implementations of intrusive containers, such\n+as Linux kernel linked lists (`struct list_head`).\n+\n+Unfortunately, although `offsetof` works for some unusual\n+member-designators, it does not work for pointers to members. This won’t\n+compile:\n+\n+<xmp>\n+\n+template <typename Container, typename Link, Link (Container::* member)>\n+Container* generic_container_from_link(Link* x) {\n+  uintptr_t x_address = reinterpret_cast<uintptr_t>(x);\n+  size_t link_offset = offsetof(Container, member); // error!\n+  return reinterpret_cast<Container*>(x_address - link_offset);\n+}\n+\n+</xmp>\n+\n+Programmers currently compute pointer-to-member offsets using `nullptr` casts\n+(i.e., the incorrect folk implementation of `offsetof`, which invokes\n+undefined behavior), or by jumping through other hoops:\n+\n+<xmp>\n+\n+template <typename Container, typename Link, Link (Container::* member)>\n+Container* generic_container_from_link(Link* x) {\n+  ...\n+  alignas(Container) char container_space[sizeof(Container)] = {};\n+  Container* fake_container = reinterpret_cast<Container*>(container_space);\n+  size_t link_offset = reinterpret_cast<uintptr_t>(&(fake_container->*member))\n+      - reinterpret_cast<uintptr_t>(fake_container);\n+  ...\n+}\n+\n+</xmp>\n+\n+`offsetof` with pointer-to-member member-designators should simply work.\n+Modern compilers implement `offsetof` using an extension (`__builtin_offsetof`\n+in GCC and LLVM), so implementation need not require library changes. To avoid\n+ambiguity, we propose this syntax:\n+\n+<xmp>\n+\n+size_t link_offset = offsetof(Container, .*member);\n+\n+</xmp>\n+\n+\n+Questions\n+=========\n+\n+Must a pointer-to-member expression in an `offsetof` member-designator be a\n+constant expression (such as a template argument)? The C standard requires\n+that “the expression `&(t.member-designator)` evaluates to an address\n+constant,” which might make this code illegal:\n+\n+<xmp>\n+\n+struct container {\n+  char array[200];\n+};\n+\n+int index = /* dynamic value */;\n+size_t offset = offsetof(container, array[index]);  // questionable\n+\n+</xmp>\n+\n+But since several current compilers accept dynamic array indexes, the proposed\n+wording allows any pointer to member.\n+\n+\n+Proposed Wording {#word}\n+================\n+\n+In Sizes, alignments, and offsets [**support.types.layout**], modify the first\n+sentence of ❡1 as follows:\n+\n+<blockquote>\n+\n+The macro `offsetof(type, member-designator)` has the same semantics as the\n+corresponding macro in the C standard library header `<stddef.h>`, but accepts\n+a restricted set of `type` arguments <ins> and a superset of\n+`member-designator` arguments </ins> in this International Standard.\n+\n+</blockquote>\n+\n+Add this paragraph after ❡1:\n+\n+<blockquote>\n+\n+<ins> An `offsetof` `member-designator` may contain pointer-to-member\n+expressions as well as `member-designators` acceptable in C. A\n+`member-designator` may begin with a prefix `.` or `.*` operator (e.g.,\n+`offsetof(type, .member_name)` or `offsetof(type, .*pointer_to_member)`). If\n+the prefix operator is omitted, `.` is assumed. </ins>\n+\n+</blockquote>\n+\n+\n+Example online discussions of the issue\n+=======================================\n+\n+https://groups.google.com/forum/#!topic/llvm-dev/l78RQ9zJR64\n+https://gist.github.com/graphitemaster/494f21190bb2c63c5516","path":"source/Doffsetof.bs","position":141,"original_position":141,"commit_id":"6a3cdfaacab051baea752dcc9dc2f5d92dfd9363","original_commit_id":"6a3cdfaacab051baea752dcc9dc2f5d92dfd9363","user":{"login":"jfbastien","id":298127,"avatar_url":"https://avatars3.githubusercontent.com/u/298127?v=4","gravatar_id":"","url":"https://api.github.com/users/jfbastien","html_url":"https://github.com/jfbastien","followers_url":"https://api.github.com/users/jfbastien/followers","following_url":"https://api.github.com/users/jfbastien/following{/other_user}","gists_url":"https://api.github.com/users/jfbastien/gists{/gist_id}","starred_url":"https://api.github.com/users/jfbastien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jfbastien/subscriptions","organizations_url":"https://api.github.com/users/jfbastien/orgs","repos_url":"https://api.github.com/users/jfbastien/repos","events_url":"https://api.github.com/users/jfbastien/events{/privacy}","received_events_url":"https://api.github.com/users/jfbastien/received_events","type":"User","site_admin":false},"body":"I'd use a list here.","created_at":"2018-02-07T22:09:44Z","updated_at":"2018-02-07T22:09:49Z","html_url":"https://github.com/jfbastien/papers/pull/48#discussion_r166772228","pull_request_url":"https://api.github.com/repos/jfbastien/papers/pulls/48","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/comments/166772228"},"html":{"href":"https://github.com/jfbastien/papers/pull/48#discussion_r166772228"},"pull_request":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/48"}}},"pull_request":{"url":"https://api.github.com/repos/jfbastien/papers/pulls/48","id":167819168,"html_url":"https://github.com/jfbastien/papers/pull/48","diff_url":"https://github.com/jfbastien/papers/pull/48.diff","patch_url":"https://github.com/jfbastien/papers/pull/48.patch","issue_url":"https://api.github.com/repos/jfbastien/papers/issues/48","number":48,"state":"open","locked":false,"title":"Pointer-to-member offsetof draft","user":{"login":"kohler","id":410647,"avatar_url":"https://avatars2.githubusercontent.com/u/410647?v=4","gravatar_id":"","url":"https://api.github.com/users/kohler","html_url":"https://github.com/kohler","followers_url":"https://api.github.com/users/kohler/followers","following_url":"https://api.github.com/users/kohler/following{/other_user}","gists_url":"https://api.github.com/users/kohler/gists{/gist_id}","starred_url":"https://api.github.com/users/kohler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohler/subscriptions","organizations_url":"https://api.github.com/users/kohler/orgs","repos_url":"https://api.github.com/users/kohler/repos","events_url":"https://api.github.com/users/kohler/events{/privacy}","received_events_url":"https://api.github.com/users/kohler/received_events","type":"User","site_admin":false},"body":"Figured this might be the easiest way to get feedback! Thanks!\r\n\r\nEddie\r\n","created_at":"2018-02-07T21:52:11Z","updated_at":"2018-02-07T22:09:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"20feb4321b8ddb1fd392c4ecdea4e529afad549b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"milestone":null,"commits_url":"https://api.github.com/repos/jfbastien/papers/pulls/48/commits","review_comments_url":"https://api.github.com/repos/jfbastien/papers/pulls/48/comments","review_comment_url":"https://api.github.com/repos/jfbastien/papers/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jfbastien/papers/issues/48/comments","statuses_url":"https://api.github.com/repos/jfbastien/papers/statuses/6a3cdfaacab051baea752dcc9dc2f5d92dfd9363","head":{"label":"kohler:master","ref":"master","sha":"6a3cdfaacab051baea752dcc9dc2f5d92dfd9363","user":{"login":"kohler","id":410647,"avatar_url":"https://avatars2.githubusercontent.com/u/410647?v=4","gravatar_id":"","url":"https://api.github.com/users/kohler","html_url":"https://github.com/kohler","followers_url":"https://api.github.com/users/kohler/followers","following_url":"https://api.github.com/users/kohler/following{/other_user}","gists_url":"https://api.github.com/users/kohler/gists{/gist_id}","starred_url":"https://api.github.com/users/kohler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohler/subscriptions","organizations_url":"https://api.github.com/users/kohler/orgs","repos_url":"https://api.github.com/users/kohler/repos","events_url":"https://api.github.com/users/kohler/events{/privacy}","received_events_url":"https://api.github.com/users/kohler/received_events","type":"User","site_admin":false},"repo":{"id":120668083,"name":"jfbastien-cpp-papers","full_name":"kohler/jfbastien-cpp-papers","owner":{"login":"kohler","id":410647,"avatar_url":"https://avatars2.githubusercontent.com/u/410647?v=4","gravatar_id":"","url":"https://api.github.com/users/kohler","html_url":"https://github.com/kohler","followers_url":"https://api.github.com/users/kohler/followers","following_url":"https://api.github.com/users/kohler/following{/other_user}","gists_url":"https://api.github.com/users/kohler/gists{/gist_id}","starred_url":"https://api.github.com/users/kohler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohler/subscriptions","organizations_url":"https://api.github.com/users/kohler/orgs","repos_url":"https://api.github.com/users/kohler/repos","events_url":"https://api.github.com/users/kohler/events{/privacy}","received_events_url":"https://api.github.com/users/kohler/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kohler/jfbastien-cpp-papers","description":"Papers for the C++ Standards Committee, WG21","fork":true,"url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers","forks_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/forks","keys_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/teams","hooks_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/hooks","issue_events_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/issues/events{/number}","events_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/events","assignees_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/assignees{/user}","branches_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/branches{/branch}","tags_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/tags","blobs_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/git/refs{/sha}","trees_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/statuses/{sha}","languages_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/languages","stargazers_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/stargazers","contributors_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/contributors","subscribers_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/subscribers","subscription_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/subscription","commits_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/commits{/sha}","git_commits_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/git/commits{/sha}","comments_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/comments{/number}","issue_comment_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/issues/comments{/number}","contents_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/contents/{+path}","compare_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/merges","archive_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/downloads","issues_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/issues{/number}","pulls_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/pulls{/number}","milestones_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/milestones{/number}","notifications_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/labels{/name}","releases_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/releases{/id}","deployments_url":"https://api.github.com/repos/kohler/jfbastien-cpp-papers/deployments","created_at":"2018-02-07T20:32:17Z","updated_at":"2018-02-07T20:32:43Z","pushed_at":"2018-02-07T21:50:47Z","git_url":"git://github.com/kohler/jfbastien-cpp-papers.git","ssh_url":"git@github.com:kohler/jfbastien-cpp-papers.git","clone_url":"https://github.com/kohler/jfbastien-cpp-papers.git","svn_url":"https://github.com/kohler/jfbastien-cpp-papers","homepage":null,"size":277,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"jfbastien:master","ref":"master","sha":"45a0799b4ad58c2851afbbf9eb939df7d6e1b8f2","user":{"login":"jfbastien","id":298127,"avatar_url":"https://avatars3.githubusercontent.com/u/298127?v=4","gravatar_id":"","url":"https://api.github.com/users/jfbastien","html_url":"https://github.com/jfbastien","followers_url":"https://api.github.com/users/jfbastien/followers","following_url":"https://api.github.com/users/jfbastien/following{/other_user}","gists_url":"https://api.github.com/users/jfbastien/gists{/gist_id}","starred_url":"https://api.github.com/users/jfbastien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jfbastien/subscriptions","organizations_url":"https://api.github.com/users/jfbastien/orgs","repos_url":"https://api.github.com/users/jfbastien/repos","events_url":"https://api.github.com/users/jfbastien/events{/privacy}","received_events_url":"https://api.github.com/users/jfbastien/received_events","type":"User","site_admin":false},"repo":{"id":33552352,"name":"papers","full_name":"jfbastien/papers","owner":{"login":"jfbastien","id":298127,"avatar_url":"https://avatars3.githubusercontent.com/u/298127?v=4","gravatar_id":"","url":"https://api.github.com/users/jfbastien","html_url":"https://github.com/jfbastien","followers_url":"https://api.github.com/users/jfbastien/followers","following_url":"https://api.github.com/users/jfbastien/following{/other_user}","gists_url":"https://api.github.com/users/jfbastien/gists{/gist_id}","starred_url":"https://api.github.com/users/jfbastien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jfbastien/subscriptions","organizations_url":"https://api.github.com/users/jfbastien/orgs","repos_url":"https://api.github.com/users/jfbastien/repos","events_url":"https://api.github.com/users/jfbastien/events{/privacy}","received_events_url":"https://api.github.com/users/jfbastien/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jfbastien/papers","description":"Papers for the C++ Standards Committee, WG21","fork":false,"url":"https://api.github.com/repos/jfbastien/papers","forks_url":"https://api.github.com/repos/jfbastien/papers/forks","keys_url":"https://api.github.com/repos/jfbastien/papers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jfbastien/papers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jfbastien/papers/teams","hooks_url":"https://api.github.com/repos/jfbastien/papers/hooks","issue_events_url":"https://api.github.com/repos/jfbastien/papers/issues/events{/number}","events_url":"https://api.github.com/repos/jfbastien/papers/events","assignees_url":"https://api.github.com/repos/jfbastien/papers/assignees{/user}","branches_url":"https://api.github.com/repos/jfbastien/papers/branches{/branch}","tags_url":"https://api.github.com/repos/jfbastien/papers/tags","blobs_url":"https://api.github.com/repos/jfbastien/papers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jfbastien/papers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jfbastien/papers/git/refs{/sha}","trees_url":"https://api.github.com/repos/jfbastien/papers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jfbastien/papers/statuses/{sha}","languages_url":"https://api.github.com/repos/jfbastien/papers/languages","stargazers_url":"https://api.github.com/repos/jfbastien/papers/stargazers","contributors_url":"https://api.github.com/repos/jfbastien/papers/contributors","subscribers_url":"https://api.github.com/repos/jfbastien/papers/subscribers","subscription_url":"https://api.github.com/repos/jfbastien/papers/subscription","commits_url":"https://api.github.com/repos/jfbastien/papers/commits{/sha}","git_commits_url":"https://api.github.com/repos/jfbastien/papers/git/commits{/sha}","comments_url":"https://api.github.com/repos/jfbastien/papers/comments{/number}","issue_comment_url":"https://api.github.com/repos/jfbastien/papers/issues/comments{/number}","contents_url":"https://api.github.com/repos/jfbastien/papers/contents/{+path}","compare_url":"https://api.github.com/repos/jfbastien/papers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jfbastien/papers/merges","archive_url":"https://api.github.com/repos/jfbastien/papers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jfbastien/papers/downloads","issues_url":"https://api.github.com/repos/jfbastien/papers/issues{/number}","pulls_url":"https://api.github.com/repos/jfbastien/papers/pulls{/number}","milestones_url":"https://api.github.com/repos/jfbastien/papers/milestones{/number}","notifications_url":"https://api.github.com/repos/jfbastien/papers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jfbastien/papers/labels{/name}","releases_url":"https://api.github.com/repos/jfbastien/papers/releases{/id}","deployments_url":"https://api.github.com/repos/jfbastien/papers/deployments","created_at":"2015-04-07T15:41:34Z","updated_at":"2018-01-31T14:37:47Z","pushed_at":"2018-02-07T21:52:12Z","git_url":"git://github.com/jfbastien/papers.git","ssh_url":"git@github.com:jfbastien/papers.git","clone_url":"https://github.com/jfbastien/papers.git","svn_url":"https://github.com/jfbastien/papers","homepage":null,"size":277,"stargazers_count":20,"watchers_count":20,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":8,"license":null,"forks":6,"open_issues":8,"watchers":20,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/48"},"html":{"href":"https://github.com/jfbastien/papers/pull/48"},"issue":{"href":"https://api.github.com/repos/jfbastien/papers/issues/48"},"comments":{"href":"https://api.github.com/repos/jfbastien/papers/issues/48/comments"},"review_comments":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/48/comments"},"review_comment":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jfbastien/papers/pulls/48/commits"},"statuses":{"href":"https://api.github.com/repos/jfbastien/papers/statuses/6a3cdfaacab051baea752dcc9dc2f5d92dfd9363"}},"author_association":"NONE"}}
{"actor":{"display_login":"jfbastien"}}