{"action":"created","issue":{"url":"https://api.github.com/repos/kripken/emscripten/issues/3301","labels_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/labels{/name}","comments_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/comments","events_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/events","html_url":"https://github.com/kripken/emscripten/issues/3301","id":65935737,"number":3301,"title":"Glitch in structure members access","user":{"login":"Olivier-myriad","id":11772212,"avatar_url":"https://avatars.githubusercontent.com/u/11772212?v=3","gravatar_id":"","url":"https://api.github.com/users/Olivier-myriad","html_url":"https://github.com/Olivier-myriad","followers_url":"https://api.github.com/users/Olivier-myriad/followers","following_url":"https://api.github.com/users/Olivier-myriad/following{/other_user}","gists_url":"https://api.github.com/users/Olivier-myriad/gists{/gist_id}","starred_url":"https://api.github.com/users/Olivier-myriad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Olivier-myriad/subscriptions","organizations_url":"https://api.github.com/users/Olivier-myriad/orgs","repos_url":"https://api.github.com/users/Olivier-myriad/repos","events_url":"https://api.github.com/users/Olivier-myriad/events{/privacy}","received_events_url":"https://api.github.com/users/Olivier-myriad/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-04-02T14:12:11Z","updated_at":"2015-04-03T13:34:19Z","closed_at":"2015-04-02T14:19:15Z","body":"Hi,\r\n\r\nAfter trying \"Hello world\", I decided to give a shot with a more complex project.\r\n\r\nI then got an issue that I can reproduce each time, but is too embedded in my project (20 plain-C source files) to be extracted. \r\n\r\nHere is what I get, after working on some data structure:\r\nA function sets masque->lettres.items (unsigned long) to 1.\r\nThen, I have :\r\n\r\n`printf(\"Addr %08lx size %d content %lu\\n\",`\r\n`   (long)&(masque->lettres.items),`\r\n`   sizeof(masque->lettres.items),`\r\n`   masque->lettres.items);`\r\n\r\n`printf(\"Memory at %08lx = %lu\\n\",`\r\n`     (long)&(masque->lettres.items),`\r\n`     *(unsigned long *)&(masque->lettres.items));`\r\n\r\nWhatever I did before, the content of memory should be equal to the structure member. Hence, the output is :\r\n\r\n`Addr 005bdcf6 size 4 content 1703936`\r\n`Memory at 005bdcf6 = 1`\r\n\r\nHow can it be explained otherwise than an error in the Emscripten compiler?\r\n\r\nNote : I compiled my whole project using the -g4 option, as well as -s ALLOW_MEMORY_GROWTH=1.\r\n\r\nDoes anybody have a clue?\r\n\r\nThanks,\r\n"},"comment":{"url":"https://api.github.com/repos/kripken/emscripten/issues/comments/89289119","html_url":"https://github.com/kripken/emscripten/issues/3301#issuecomment-89289119","issue_url":"https://api.github.com/repos/kripken/emscripten/issues/3301","id":89289119,"user":{"login":"Olivier-myriad","id":11772212,"avatar_url":"https://avatars.githubusercontent.com/u/11772212?v=3","gravatar_id":"","url":"https://api.github.com/users/Olivier-myriad","html_url":"https://github.com/Olivier-myriad","followers_url":"https://api.github.com/users/Olivier-myriad/followers","following_url":"https://api.github.com/users/Olivier-myriad/following{/other_user}","gists_url":"https://api.github.com/users/Olivier-myriad/gists{/gist_id}","starred_url":"https://api.github.com/users/Olivier-myriad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Olivier-myriad/subscriptions","organizations_url":"https://api.github.com/users/Olivier-myriad/orgs","repos_url":"https://api.github.com/users/Olivier-myriad/repos","events_url":"https://api.github.com/users/Olivier-myriad/events{/privacy}","received_events_url":"https://api.github.com/users/Olivier-myriad/received_events","type":"User","site_admin":false},"created_at":"2015-04-03T13:34:19Z","updated_at":"2015-04-03T13:34:19Z","body":"I respectfully disagree.\r\n\r\nIf b is a 32-bits int, the expression `*(uint32_t*)&(f.b))` should *always* provide an aligned pointer on the 4-bytes data that actually contains the value of this member, whatever the alignment chosen by the compiler. \r\nOtherwise, it's a fault in the compiler.\r\n\r\n**If `<expr>` is a long int, `*(long *)&(<expr>)` has to be equal to `<expr>`. Always.** \r\n\r\nIn C, if you get the address of a variable, a structure member, or an array element, as well as its size through `sizeof` and if you binary preserve `<size>` bytes from this address, you will preserve the actual content of the item, not some random fillers that could have been added by the compiler to align the members.\r\n\r\nIn C, you can write a function that receives a pointer, and work on the content of this pointer.\r\n\r\nIf you write:\r\n```\r\n#pragma pack(2)\r\nstruct Foo\r\n{\r\nint16 a;\r\nint32 b;\r\n};\r\n\r\nvoid SetLong(int32 * addr,int32 value)\r\n{\r\n*addr=value;\r\n}\r\n\r\nint main(void)\r\n{\r\nstruct Foo f;\r\nint32 i;\r\n\r\nSetLong(&i,10);\r\nprintf(\"i= %ld\\n\",i);\r\nSetLong(&(f.b),10);\r\nprintf(\"f.b= %ld\\n\",f.b);\r\n}\r\n```\r\nyou don't have to worry whether the address sent to the \"SetLong\" function points to a single variable, a structure member or an array element. It should work, period. There is just no reason for the compiler to align the pointer to a 4-bytes boundary when getting &(f.b), since pack(2) is supported and longs can be read and write on unaligned addresses. "}}