Pointer to inside an array

A

Alok Singhal

Hi,

Let's say I have:

int a[20] = {0};

Is the declaration below legal according to C89?

int (*p)[5] = (int (*)[5])(a+6);
 
M

mohangupta13

Hi,

Let's say I have:

int a[20] = {0};

Is the declaration below legal according to C89?

int (*p)[5] = (int (*)[5])(a+6);
As far as i think (i am not 100% certain though) its legal. But in
this case only (p+2)[3] can be safely addressed for storing values.

Mohan
 
A

annalissa

Let's say I have:
int a[20] = {0};
Is the declaration below legal according to C89?
int (*p)[5] = (int (*)[5])(a+6);

consider this program:-

#include<stdio.h>
#include<stdlib.h>

int main(void)
{

int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

printf("\n %d",(*p)[0]);

return(EXIT_SUCCESS);
}

compile this program as gcc -g -ansi -pedantic -o progname
progname.c , then decide for yourself


As far as i think (i am not 100% certain though) its legal. But in
this case only (p+2)[3] can be safely addressed for storing values.

what do you mean by the statement that (p+2)[3] can be safely
addressed for storing values. ???
 
M

mohangupta13

Let's say I have:
int a[20] = {0};
Is the declaration below legal according to C89?
int (*p)[5] = (int (*)[5])(a+6);

consider this program:-

#include<stdio.h>
#include<stdlib.h>

int main(void)
{

 int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

  int (*p)[5] = (int(*)[5])(a+6);

  printf("\n %d",(*p)[0]);

  return(EXIT_SUCCESS);

}

compile this program as gcc -g -ansi -pedantic -o progname
progname.c , then decide for yourself
As far as i think (i am not 100% certain though) its legal. But in
this case only (p+2)[3] can be safely addressed for storing values.

what do you mean by the statement that (p+2)[3] can be safely
addressed for storing values. ???

well i meant that the last value accessible through p is (p+2)[3] it
should be the value at a[19].
 
A

Alok Singhal

consider this program:-

#include<stdio.h>
#include<stdlib.h>

int main(void)
{

int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

printf("\n %d",(*p)[0]);

return(EXIT_SUCCESS);
}

compile this program as gcc -g -ansi -pedantic -o progname progname.c ,
then decide for yourself

Yes, gcc doesn't give any warnings, but we are casting p to what we
want. If we remove the cast, gcc does give a warning saying:
"initialization from incompatible pointer type". I understand that the
initialization is from an incompatible pointer type, so I *think* this
means that the behavior is undefined. But I am not sure.

Thanks,
Alok
 
B

Ben Bacarisse

mohangupta13 said:
On Dec 15, 4:03 pm, Alok  Singhal <[email protected]> wrote:> Hi,
Let's say I have:
int a[20] = {0};
Is the declaration below legal according to C89?
int (*p)[5] = (int (*)[5])(a+6);
As far as i think (i am not 100% certain though) its legal.

"Legal" is an odd word in this context. The conversion between the
two pointer types is implementation defined so I suppose pretty much
any result is possible though there is an "obvious" conversion.
But in
this case only (p+2)[3] can be safely addressed for storing values.

what do you mean by the statement that (p+2)[3] can be safely
addressed for storing values. ???

well i meant that the last value accessible through p is (p+2)[3] it
should be the value at a[19].

(p+2)[3] and a[19] have different types. You probably meant
(*(p+2))[3] but that is simpler to right as p[2][3].
 
B

Barry Schwarz

consider this program:-

#include<stdio.h>
#include<stdlib.h>

int main(void)
{

int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

printf("\n %d",(*p)[0]);

return(EXIT_SUCCESS);
}

compile this program as gcc -g -ansi -pedantic -o progname progname.c ,
then decide for yourself

Yes, gcc doesn't give any warnings, but we are casting p to what we
want. If we remove the cast, gcc does give a warning saying:
"initialization from incompatible pointer type". I understand that the
initialization is from an incompatible pointer type, so I *think* this
means that the behavior is undefined. But I am not sure.

Think again. The purpose of the cast is not to silence the warning
but to coerce the value of the expression to a compatible type and
eliminate the condition that requires a diagnostic.

The code
unsigned char *ptr = (unsigned char*)(a+6);
will produce the exact same warning without the cast yet the
initialization is perfectly well defined as written.
 
P

Peter Nilsson

annalissa said:
mohangupta13 said:
Alok  Singhal said:
Let's say I have:

int a[20] = {0};

Is the declaration below legal according to C89?

int (*p)[5] = (int (*)[5])(a+6);

Depends on wheather a+6 is properly aligned for an int(*)[5].
If not, then no, it's not valid. I don't believe the standard
guarantees you can dereference it, only convert it back to an
int *. Also, you are accessing part of an object using a
different type to the effective type.
consider this program:-
compile this program as gcc -g -ansi -pedantic -o progname
progname.c , then decide for yourself

That something compiles without a diagnostic under gcc does not
mean it is correct. E.g. ...

int main(void) { return * (int *) 0; }
 
A

annalissa

annalissa said:
mohangupta13 said:
Let's say I have:
int a[20] = {0};
Is the declaration below legal according to C89?
int (*p)[5] = (int (*)[5])(a+6);

Depends on wheather a+6 is properly aligned for an int(*)[5].
If not, then no, it's not valid. I don't believe the standard
guarantees you can dereference it, only convert it back to an
int *. Also, you are accessing part of an object using a
different type to the effective type.


consider this program:-
compile this program as gcc -g -ansi -pedantic -o progname
progname.c , then decide for yourself

That something compiles without a diagnostic under gcc does not
mean it is correct. E.g. ...

  int main(void) { return * (int *) 0; }


what is the diagnostic that i am missing ..??
 
A

Alok Singhal

int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

Think again. The purpose of the cast is not to silence the warning but
to coerce the value of the expression to a compatible type and eliminate
the condition that requires a diagnostic.

The code
unsigned char *ptr = (unsigned char*)(a+6);
will produce the exact same warning without the cast yet the
initialization is perfectly well defined as written.

Thanks. This is what I was looking for. I should have read the standard
more carefully as well. So 6.3.2.3p7 (N1336) applies here:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer.

There is no guarantee that int (*)[5] is correctly aligned for int *, and
even if it is, the standard makes no guarantees about dereferencing such
a pointer.

-Alok
 
B

Barry Schwarz

int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

Think again. The purpose of the cast is not to silence the warning but
to coerce the value of the expression to a compatible type and eliminate
the condition that requires a diagnostic.

The code
unsigned char *ptr = (unsigned char*)(a+6);
will produce the exact same warning without the cast yet the
initialization is perfectly well defined as written.

Thanks. This is what I was looking for. I should have read the standard
more carefully as well. So 6.3.2.3p7 (N1336) applies here:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer.

There is no guarantee that int (*)[5] is correctly aligned for int *, and
even if it is, the standard makes no guarantees about dereferencing such
a pointer.

Do you just invent these assumptions or do you read them somewhere
that we can tell others to avoid?

int array[5] = {2};
int (*ptr_a)[5] = &array;
int *ptr_i = array;

Is there any doubt in your mind that both pointers point to the same
address in memory? Is there any doubt that the expression
(unsigned char*)ptr_a == (unsigned char*)ptr_i
will evaluate to 1.

Is there any doubt in your mind that ptr_i[0] references the first
element of the array and evaluates to 2 while ptr_i[1] references the
second element and evaluates to 0?

Is there any doubt in your mind ptr_a[0][0] and ptr_a[0][1] reference
the exact same objects and hence must evaluate to the same values?
 
B

Barry Schwarz

annalissa said:
Let's say I have:
int a[20] = {0};
Is the declaration below legal according to C89?
int (*p)[5] = (int (*)[5])(a+6);

Depends on wheather a+6 is properly aligned for an int(*)[5].
If not, then no, it's not valid. I don't believe the standard
guarantees you can dereference it, only convert it back to an
int *. Also, you are accessing part of an object using a
different type to the effective type.


consider this program:-
compile this program as gcc -g -ansi -pedantic -o progname
progname.c , then decide for yourself

That something compiles without a diagnostic under gcc does not
mean it is correct. E.g. ...

  int main(void) { return * (int *) 0; }


what is the diagnostic that i am missing ..??

There is no diagnostic required but the code invokes undefined
behavior.
 
A

Alok Singhal

On Wed, 16 Dec 2009 17:50:42 +0000 (UTC), Alok Singhal
Thanks. This is what I was looking for. I should have read the
standard more carefully as well. So 6.3.2.3p7 (N1336) applies here:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer.

There is no guarantee that int (*)[5] is correctly aligned for int *,
and even if it is, the standard makes no guarantees about dereferencing
such a pointer.

Do you just invent these assumptions or do you read them somewhere that
we can tell others to avoid?

Please bear with me while I try to explain myself. Isn't there a
difference between:

int array[5] = {2};
int (*ptr)[5] = &array;

and:

int array[20] = {2};
int (*ptr)[5] = (int (*)[5])(array + 6);

In the second snippet, "array + 6" is of type "pointer to int". In the
first snippet, "&array" is of type "int (*)[5]". So, if I understand
correctly, and I think that is what you're saying too: the first snippet
is well-defined by the standard, while the result second snippet, in
particular the assignment to "ptr" is implementation-defined.

So, *if I understand correctly*, in the second snippet above:

- the cast is needed because it coerces "a+6" to the correct type for
"ptr".
- if "ptr" is a pointer to (signed or unsigned) char, or any other type
that is correctly aligned for the type of "a+6" (int *), the
initialization is well-defined in that I can convert "ptr" back to
int * and get the same value.
- if "ptr" isn't correctly aligned for int *, the result of the
initialization is implementation-defined.

Please let me know where I am wrong in my assumptions.
int array[5] = {2};
int (*ptr_a)[5] = &array;
int *ptr_i = array;

Is there any doubt in your mind that both pointers point to the same
address in memory? Is there any doubt that the expression
(unsigned char*)ptr_a == (unsigned char*)ptr_i
will evaluate to 1.

Is there any doubt in your mind that ptr_i[0] references the first
element of the array and evaluates to 2 while ptr_i[1] references the
second element and evaluates to 0?

Is there any doubt in your mind ptr_a[0][0] and ptr_a[0][1] reference
the exact same objects and hence must evaluate to the same values?

The answer to all the above questions is, "no". I agree with all the
statements above.

Thanks again for your help,
-Alok
 
B

Barry Schwarz

On Wed, 16 Dec 2009 17:50:42 +0000 (UTC), Alok Singhal
Thanks. This is what I was looking for. I should have read the
standard more carefully as well. So 6.3.2.3p7 (N1336) applies here:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer.

There is no guarantee that int (*)[5] is correctly aligned for int *,
and even if it is, the standard makes no guarantees about dereferencing
such a pointer.

Do you just invent these assumptions or do you read them somewhere that
we can tell others to avoid?

Please bear with me while I try to explain myself. Isn't there a
difference between:

int array[5] = {2};
int (*ptr)[5] = &array;

and:

int array[20] = {2};
int (*ptr)[5] = (int (*)[5])(array + 6);

In the second snippet, "array + 6" is of type "pointer to int". In the
first snippet, "&array" is of type "int (*)[5]". So, if I understand
correctly, and I think that is what you're saying too: the first snippet
is well-defined by the standard, while the result second snippet, in
particular the assignment to "ptr" is implementation-defined.

So, *if I understand correctly*, in the second snippet above:

- the cast is needed because it coerces "a+6" to the correct type for
"ptr".
- if "ptr" is a pointer to (signed or unsigned) char, or any other type
that is correctly aligned for the type of "a+6" (int *), the
initialization is well-defined in that I can convert "ptr" back to
int * and get the same value.
- if "ptr" isn't correctly aligned for int *, the result of the
initialization is implementation-defined.

If the value a+6 is correctly aligned for the type int(*)[5], then
your initialization of ptr is well defined. If not, the
initialization invokes undefined behavior (6.3.2.3-7), not
implementation defined behavior. So the question revolves around
whether a+6 is properly aligned.

Consider the definition
int x[sizeof(int)][5];

We know that each element x[j] occupies exactly sizeof(int) bytes.
Further more, each element x[j+1] starts exactly sizeof(int) bytes
beyond the start of the previous element x[j] (except for the
obvious boundary condition when j==4).

We also know that each x is an array of 5 int and that x[i+1]
starts exactly 5*sizeof(int) bytes beyond the start of x (again
except for the boundary condition when i==sizeof(int)-1).

Because sizeof(int) is not a factor of 5, I assert the x as a group
completely exhaust all possible alignments for int[5] and that they
also completely exhaust all possible alignments for int. (I don't
remember what the branch of mathematics is called that is used to
prove these assertions but if you choose both common (2, 4, and 8) and
off-the-wall (3, 15 23) values for sizeof(int) and work out the
addresses you should be convinced.) Consequently, the value a+6 will
exactly match the alignment of at least one of the x and is
therefore properly aligned.
 
P

Peter Nilsson

Barry Schwarz said:
Alok Singhal
Please bear with me while I try to explain myself. Isn't
there a difference between:

int array[5] = {2};
int (*ptr)[5] = &array;

and:

int array[20] = {2};
int (*ptr)[5] = (int (*)[5])(array + 6);

...the question revolves around whether a+6 is properly aligned.

Consider the definition
int x[sizeof(int)][5];

I have no idea why you think sizeof(int) should be used here!
We know that each element x[j] occupies exactly sizeof(int)
bytes. Further more, each element x[j+1] starts exactly
sizeof(int) bytes beyond the start of the previous element
x[j] (except for the obvious boundary condition when j==4).

We also know that each x is an array of 5 int and that
x[i+1] starts exactly 5*sizeof(int) bytes beyond the start
of x (again except for the boundary condition when i==
sizeof(int)-1).

Because sizeof(int) is not a factor of 5,


Not commonly, but on the virtual machine it may be.
I assert the x as a group completely exhaust all possible
alignments for int[5] and that they also completely exhaust
all possible alignments for int. ...


I've had a previous discussion considering something like...

int a[7];
int (*p)[2] = (int (*)[2]) (a + 1);

The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

Why should it? Look at an example using structs...

struct int_pair_t { int a; int b; };
int a[7];
struct int_pair_t *p = (struct int_pair_t *) (a + 1);

Even if one shows that there is no padding in the struct,
there is still no guarantee that a + 1 is properly aligned
for a struct int_pair_t *.

Simple question: Is there anything precluding an
implementation giving struct int_pair_t a stricter
alignment than int?

[This is ignoring the issue of effective type which plays
a further role in the discussion.]
 
B

Barry Schwarz

Barry Schwarz said:
Alok Singhal
Please bear with me while I try to explain myself. Isn't
there a difference between:

int array[5] = {2};
int (*ptr)[5] = &array;

and:

int array[20] = {2};
int (*ptr)[5] = (int (*)[5])(array + 6);

...the question revolves around whether a+6 is properly aligned.

Consider the definition
int x[sizeof(int)][5];

I have no idea why you think sizeof(int) should be used here!

I thought it would insure exhaustion but, as you point out below, it
works only for currently common implementations and fails in the
perverse case.
We know that each element x[j] occupies exactly sizeof(int)
bytes. Further more, each element x[j+1] starts exactly
sizeof(int) bytes beyond the start of the previous element
x[j] (except for the obvious boundary condition when j==4).

We also know that each x is an array of 5 int and that
x[i+1] starts exactly 5*sizeof(int) bytes beyond the start
of x (again except for the boundary condition when i==
sizeof(int)-1).

Because sizeof(int) is not a factor of 5,


Not commonly, but on the virtual machine it may be.
I assert the x as a group completely exhaust all possible
alignments for int[5] and that they also completely exhaust
all possible alignments for int. ...


I've had a previous discussion considering something like...

int a[7];
int (*p)[2] = (int (*)[2]) (a + 1);

The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.


Yes. If the dimension of the array pointed to is a factor of
sizeof(int), then my argument fails. For example, if sizeof(int) is 4
and the alignment for int[2] is 8, then obviously a+1 or a+2 must be
misaligned for p.

Applying this to the specific example under consideration where the
dimension is 5, this can happen only if the alignment for an int[5] is
a multiple of 5*sizeof(int), such as 20 to match the example. In such
a case, array+6 may or may not be properly aligned but if it is then
array+7 is definitely not.

So to the OP I apologize for the error in my response. It is probably
properly aligned on all current systems you are likely to run on but
it may very well invoke undefined behavior on the DS9K or some new
system where the alignment of int[5] is more restrictive than that of
int.
Why should it? Look at an example using structs...

struct int_pair_t { int a; int b; };
int a[7];
struct int_pair_t *p = (struct int_pair_t *) (a + 1);

Even if one shows that there is no padding in the struct,
there is still no guarantee that a + 1 is properly aligned
for a struct int_pair_t *.

Simple question: Is there anything precluding an
implementation giving struct int_pair_t a stricter
alignment than int?

[This is ignoring the issue of effective type which plays
a further role in the discussion.]
 
A

Alok Singhal

So the question revolves around whether a+6 is properly aligned.

Yes, I think I wasn't clear enough in my posts so far. This indeed
was my question to begin with.
Consider the definition
   int x[sizeof(int)][5];

We know that each element x[j] occupies exactly sizeof(int) bytes.
Further more, each element x[j+1] starts exactly sizeof(int) bytes
beyond the start of the previous element x[j] (except for the
obvious boundary condition when j==4).

We also know that each x is an array of 5 int and that x[i+1]
starts exactly 5*sizeof(int) bytes beyond the start of x (again
except for the boundary condition when i==sizeof(int)-1).

Because sizeof(int) is not a factor of 5, I assert the x as a group
completely exhaust all possible alignments for int[5] and that they
also completely exhaust all possible alignments for int.  (I don't
remember what the branch of mathematics is called that is used to
prove these assertions but if you choose both common (2, 4, and 8) and
off-the-wall (3, 15 23) values for sizeof(int) and work out the
addresses you should be convinced.)  Consequently, the value a+6 will
exactly match the alignment of at least one of the x and is
therefore properly aligned.


OK. I see. I can agree with your arguments. But sizeof(int) can be a
factor of 5 theoretically, and the number 5 in my original post is
something I picked out of convenience. In general, it could be any
number (2, 8, 4, whatever). Similarly, the same goes for the numbers
and 6, and 20 in my original post. So, given

int a[N] = {0};
int (*p)[m] = (int (*)[m])(a+k);

with N, m, k as integers (and k+m < N of course), I can't be sure if a
+k is properly aligned for int (*)[m]?

Thanks a lot for your responses!

-Alok
 
A

Alok Singhal

On Thu, 17 Dec 2009 19:45:28 -0800 (PST), Peter Nilsson

So to the OP I apologize for the error in my response.  It is probably
properly aligned on all current systems you are likely to run on but
it may very well invoke undefined behavior on the DS9K or some new
system where the alignment of int[5] is more restrictive than that of
int.

No need for the apology - I learned quite a lot from your and Peter's
answers, and I should have been more specific to begin with. After
all these years of lurking here in clc, I thought I was ready to post
an interesting question (interesting to me anyway). :)

-Alok
 
S

Seebs

The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.
Why should it? Look at an example using structs...

struct int_pair_t { int a; int b; };
int a[7];
struct int_pair_t *p = (struct int_pair_t *) (a + 1);

Even if one shows that there is no padding in the struct,
there is still no guarantee that a + 1 is properly aligned
for a struct int_pair_t *.

For a struct, this might be true. For an array, it's not.
Simple question: Is there anything precluding an
implementation giving struct int_pair_t a stricter
alignment than int?

I'm not sure. I think in practice you probably can't, because you can
set up an elaborate construct involving unions which allows you to prove
that you have to be able to treat a pointer to a large enough hunk of
space which is aligned properly for an int as a pointer to the first member
of the structure.

But structs are not the same thing as arrays. I am pretty sure that
array-of-foo has to have the same alignment requirements as foo, because
any foo can be treated as an array of 1 foo, and you can treat any pointer
to foo as an array of foo. Basically, the wording guaranteeing that
the offset in bytes of foo[1] is precisely sizeof(foo[0]) covers it.

So I'm pretty sure that arrays can't have alignment requirements more
restrictive than the alignment requirements of the things they're arrays
of.

-s
 
K

Keith Thompson

Seebs said:
The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.
Why should it? Look at an example using structs...

struct int_pair_t { int a; int b; };
int a[7];
struct int_pair_t *p = (struct int_pair_t *) (a + 1);

Even if one shows that there is no padding in the struct,
there is still no guarantee that a + 1 is properly aligned
for a struct int_pair_t *.

For a struct, this might be true. For an array, it's not.

I'd like to think that's true, but I'm not entirely convinced unless
it can be proven from the standard.
Simple question: Is there anything precluding an
implementation giving struct int_pair_t a stricter
alignment than int?

I'm not sure. I think in practice you probably can't, because you can
set up an elaborate construct involving unions which allows you to prove
that you have to be able to treat a pointer to a large enough hunk of
space which is aligned properly for an int as a pointer to the first member
of the structure.

But structs are not the same thing as arrays. I am pretty sure that
array-of-foo has to have the same alignment requirements as foo, because
any foo can be treated as an array of 1 foo, and you can treat any pointer
to foo as an array of foo. Basically, the wording guaranteeing that
the offset in bytes of foo[1] is precisely sizeof(foo[0]) covers it.

Yes, but it doesn't follow from that that an array type can't have
a stricter alignment requirement than its element type.
So I'm pretty sure that arrays can't have alignment requirements more
restrictive than the alignment requirements of the things they're arrays
of.

Consider a hypothetical implementation in which int is 4 bytes (32
bits), and the CPU has instructions that can access 4-byte and 8-byte
objects in memory, but only if they're 4-byte or 8-byte aligned.
The implementation imposes a 4-byte alignment requirement on int
objects. It also imposes an 8-byte alignment on int[N] objects,
where N is even. (The question is whether the latter requirement
is allowed.)

I declare an arr of int:

int arr2[4];

Each element is 4-byte aligned. The object as a whole is 8-byte
aligned.

For most operations, everything works just as you'd expect. The
question is whether this:

typedef int pair[2];
pair *p = (pair*)&arr2[1];

is valid, or whether operations on p can invoke undefined behavior
because of the alignment mismatch.

If an implementation causes the initialization of p to trap, for
example, what clause of the standard does the implementation violate?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top