Is this type punning well defined?
I have structure like below.
struct result{
int a;
int b;
int c;
int d;
}
and union like below.
union convert{
int arr[4];
struct result res;
}
and I type pun as below.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %dn", pointer->res.a, pointer->res.b);
c language-lawyer
add a comment |
I have structure like below.
struct result{
int a;
int b;
int c;
int d;
}
and union like below.
union convert{
int arr[4];
struct result res;
}
and I type pun as below.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %dn", pointer->res.a, pointer->res.b);
c language-lawyer
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
2
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
1
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
Hmmm, Ifstatic_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.
– chux
1 hour ago
add a comment |
I have structure like below.
struct result{
int a;
int b;
int c;
int d;
}
and union like below.
union convert{
int arr[4];
struct result res;
}
and I type pun as below.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %dn", pointer->res.a, pointer->res.b);
c language-lawyer
I have structure like below.
struct result{
int a;
int b;
int c;
int d;
}
and union like below.
union convert{
int arr[4];
struct result res;
}
and I type pun as below.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %dn", pointer->res.a, pointer->res.b);
c language-lawyer
c language-lawyer
edited 3 hours ago
AndyG
26.2k76995
26.2k76995
asked 3 hours ago
KBlrKBlr
1498
1498
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
2
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
1
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
Hmmm, Ifstatic_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.
– chux
1 hour ago
add a comment |
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
2
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
1
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
Hmmm, Ifstatic_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.
– chux
1 hour ago
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
2
2
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
1
1
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
Hmmm, If
static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.– chux
1 hour ago
Hmmm, If
static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.– chux
1 hour ago
add a comment |
5 Answers
5
active
oldest
votes
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.
– Eric Postpischil
1 hour ago
@EricPostpischil one could say that thearr1[0]
(becausearr1
is converted to a pointer to its first member before the cast) is accessed through an lvaluepointer->res.a
, which does not violate 6.5.7, because the type of the lvalue isint
and the accessed object's type isint
.
– Language Lawyer
1 hour ago
add a comment |
C imposes no rule about how much padding is left between 2 consecutive members of a structure.
This is why the implementations define many #pragma directives -- specially to change this behaviour.
So, as the answer of Bathsheba says, ...->b
is undefined.
I answered the very same question some time ago, here.
add a comment |
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1
might have address 0x1004 (not a multiple of 8).
This type punning is not well defined.
What if I add__attribute__((packed))
to structure ?
– kiran Biradar
21 secs ago
add a comment |
Pointer punning is not safe. Use real union punning instead.
Assumptions: the struct is properly packed (no padding between the members)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %dn", cnv.res.a, cnv.res.b);
}
all modern compilers will optimize out the memcpy
call
https://godbolt.org/z/4qtRIF
.LC0:
.string "%d %dn"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf
Agree. Deleted.
– Language Lawyer
18 mins ago
add a comment |
After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator ->
semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):
A postfix expression followed by the
->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
means that a postfix expression followed by the ->
operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54237976%2fis-this-type-punning-well-defined%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.
– Eric Postpischil
1 hour ago
@EricPostpischil one could say that thearr1[0]
(becausearr1
is converted to a pointer to its first member before the cast) is accessed through an lvaluepointer->res.a
, which does not violate 6.5.7, because the type of the lvalue isint
and the accessed object's type isint
.
– Language Lawyer
1 hour ago
add a comment |
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.
– Eric Postpischil
1 hour ago
@EricPostpischil one could say that thearr1[0]
(becausearr1
is converted to a pointer to its first member before the cast) is accessed through an lvaluepointer->res.a
, which does not violate 6.5.7, because the type of the lvalue isint
and the accessed object's type isint
.
– Language Lawyer
1 hour ago
add a comment |
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
answered 3 hours ago
BathshebaBathsheba
176k27251373
176k27251373
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.
– Eric Postpischil
1 hour ago
@EricPostpischil one could say that thearr1[0]
(becausearr1
is converted to a pointer to its first member before the cast) is accessed through an lvaluepointer->res.a
, which does not violate 6.5.7, because the type of the lvalue isint
and the accessed object's type isint
.
– Language Lawyer
1 hour ago
add a comment |
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.
– Eric Postpischil
1 hour ago
@EricPostpischil one could say that thearr1[0]
(becausearr1
is converted to a pointer to its first member before the cast) is accessed through an lvaluepointer->res.a
, which does not violate 6.5.7, because the type of the lvalue isint
and the accessed object's type isint
.
– Language Lawyer
1 hour ago
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
Thank you! If I ensure that there will be no padding is it then well defined?
– KBlr
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
@KBlr: Yep! Just not portable
– AndyG
3 hours ago
2
2
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.– Eric Postpischil
1 hour ago
pointer->res.a
accesses an object (arr1
) through an lvalue (pointer->res
) in violation of C 2018 6.5 7.– Eric Postpischil
1 hour ago
@EricPostpischil one could say that the
arr1[0]
(because arr1
is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a
, which does not violate 6.5.7, because the type of the lvalue is int
and the accessed object's type is int
.– Language Lawyer
1 hour ago
@EricPostpischil one could say that the
arr1[0]
(because arr1
is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a
, which does not violate 6.5.7, because the type of the lvalue is int
and the accessed object's type is int
.– Language Lawyer
1 hour ago
add a comment |
C imposes no rule about how much padding is left between 2 consecutive members of a structure.
This is why the implementations define many #pragma directives -- specially to change this behaviour.
So, as the answer of Bathsheba says, ...->b
is undefined.
I answered the very same question some time ago, here.
add a comment |
C imposes no rule about how much padding is left between 2 consecutive members of a structure.
This is why the implementations define many #pragma directives -- specially to change this behaviour.
So, as the answer of Bathsheba says, ...->b
is undefined.
I answered the very same question some time ago, here.
add a comment |
C imposes no rule about how much padding is left between 2 consecutive members of a structure.
This is why the implementations define many #pragma directives -- specially to change this behaviour.
So, as the answer of Bathsheba says, ...->b
is undefined.
I answered the very same question some time ago, here.
C imposes no rule about how much padding is left between 2 consecutive members of a structure.
This is why the implementations define many #pragma directives -- specially to change this behaviour.
So, as the answer of Bathsheba says, ...->b
is undefined.
I answered the very same question some time ago, here.
edited 2 hours ago
answered 3 hours ago
alinsoaralinsoar
8,12613047
8,12613047
add a comment |
add a comment |
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1
might have address 0x1004 (not a multiple of 8).
This type punning is not well defined.
What if I add__attribute__((packed))
to structure ?
– kiran Biradar
21 secs ago
add a comment |
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1
might have address 0x1004 (not a multiple of 8).
This type punning is not well defined.
What if I add__attribute__((packed))
to structure ?
– kiran Biradar
21 secs ago
add a comment |
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1
might have address 0x1004 (not a multiple of 8).
This type punning is not well defined.
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1
might have address 0x1004 (not a multiple of 8).
This type punning is not well defined.
edited 48 mins ago
answered 58 mins ago
chuxchux
81.6k871148
81.6k871148
What if I add__attribute__((packed))
to structure ?
– kiran Biradar
21 secs ago
add a comment |
What if I add__attribute__((packed))
to structure ?
– kiran Biradar
21 secs ago
What if I add
__attribute__((packed))
to structure ?– kiran Biradar
21 secs ago
What if I add
__attribute__((packed))
to structure ?– kiran Biradar
21 secs ago
add a comment |
Pointer punning is not safe. Use real union punning instead.
Assumptions: the struct is properly packed (no padding between the members)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %dn", cnv.res.a, cnv.res.b);
}
all modern compilers will optimize out the memcpy
call
https://godbolt.org/z/4qtRIF
.LC0:
.string "%d %dn"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf
Agree. Deleted.
– Language Lawyer
18 mins ago
add a comment |
Pointer punning is not safe. Use real union punning instead.
Assumptions: the struct is properly packed (no padding between the members)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %dn", cnv.res.a, cnv.res.b);
}
all modern compilers will optimize out the memcpy
call
https://godbolt.org/z/4qtRIF
.LC0:
.string "%d %dn"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf
Agree. Deleted.
– Language Lawyer
18 mins ago
add a comment |
Pointer punning is not safe. Use real union punning instead.
Assumptions: the struct is properly packed (no padding between the members)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %dn", cnv.res.a, cnv.res.b);
}
all modern compilers will optimize out the memcpy
call
https://godbolt.org/z/4qtRIF
.LC0:
.string "%d %dn"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf
Pointer punning is not safe. Use real union punning instead.
Assumptions: the struct is properly packed (no padding between the members)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %dn", cnv.res.a, cnv.res.b);
}
all modern compilers will optimize out the memcpy
call
https://godbolt.org/z/4qtRIF
.LC0:
.string "%d %dn"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf
answered 3 hours ago
P__J__P__J__
9,4912723
9,4912723
Agree. Deleted.
– Language Lawyer
18 mins ago
add a comment |
Agree. Deleted.
– Language Lawyer
18 mins ago
Agree. Deleted.
– Language Lawyer
18 mins ago
Agree. Deleted.
– Language Lawyer
18 mins ago
add a comment |
After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator ->
semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):
A postfix expression followed by the
->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
means that a postfix expression followed by the ->
operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert
.
add a comment |
After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator ->
semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):
A postfix expression followed by the
->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
means that a postfix expression followed by the ->
operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert
.
add a comment |
After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator ->
semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):
A postfix expression followed by the
->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
means that a postfix expression followed by the ->
operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert
.
After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator ->
semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):
A postfix expression followed by the
->
operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.
means that a postfix expression followed by the ->
operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert
.
edited 1 hour ago
answered 1 hour ago
Language LawyerLanguage Lawyer
115111
115111
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54237976%2fis-this-type-punning-well-defined%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
@StoryTeller I'm sorry, it typing mistake.
– KBlr
3 hours ago
2
Id you can assure no paddign in the structure - it is safe at list with gcc
– P__J__
3 hours ago
@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?
– Bathsheba
3 hours ago
1
@Bathsheba: Darn me and me illiteracy
– AndyG
3 hours ago
Hmmm, If
static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm");
was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.– chux
1 hour ago