-1

The C standard states (emphasize mine):

28 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.48) Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

48) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.

Source: C11, §6.2.5/28

The wording of "the same representation and alignment" happens here often.

But what about the same size?

I wonder if there can be a difference between between these pointer objects in terms of the allocated size since the size of a pointer object can vary between the type pointed to even if the alignment and representation is the same.

Or in other words: Is there a guarantee that if the alignment and/or representation is equal, the size is so too?

Question:

  • Is the size of an object equivalent to the size of another based upon the same alignment and/or representation?

Annotations:

  • The question is not specific to pointer objects only. The pointer guidance was just a reference to my mindset as it is a good example.

  • Citations from the standard are highly appreciated. Accepted answer must have quotations from the standard.

  • Setting is the exact same specific implementation. I don't talk about various alignments/representations/sizes of objects between different implementations.


Related (regarding the pointer example):

  • However, pointers will always be the same size. But not always equal to 4 because that depends on the addressable memory size of the implementation, but per implementation it will always be the same size. – Paul Ogilvie Jul 11 '20 at 09:55
  • @P__J__ Thank you. Rephrased the question to be more specific. – RobertS supports Monica Cellio Jul 11 '20 at 09:58
  • 1
    @PaulOgilvie Doesn't that contradict to [this answer](https://stackoverflow.com/a/399030/12139179)? – RobertS supports Monica Cellio Jul 11 '20 at 10:16
  • I find it hard to imagine an example of an object that would have the same representation but different size. However, i don't know whether the standard unambiguously specifies the meaning of "representation". I just assume that it includes the size, not sure about alignment though. – Felix G Jul 11 '20 at 10:24
  • 2
    @PaulOgilvie: The C standard does not require pointers to be all the same size. (Certain subsets of pointers must be the same size as each other. Pointers to `void` and character types must be the same size as each other. Pointers to structures must be the same size as each other. But a pointer to a function does not need to be the same size as a pointer to an object. A pointer to an `int` does not need to be the same size as a pointer to an array of `int`.) – Eric Postpischil Jul 11 '20 at 11:17
  • Hmmm I could see a unicorn implementation with a 16-byte `long double` using 10 bytes of info and 6-bytes of padding along with another FP type `float10` that uses the same encoding but not the padding. Deeper: RobertS, once you has the Y/N answer to "Is the size of an object equivalent to the size of another based upon the same alignment and/or representation?", how does it affect your coding? – chux - Reinstate Monica Jul 11 '20 at 14:24
  • @chux-ReinstateMonica The background is that I came across the technique to use a pointer to an incomplete structure type used as member of another structure, like [here](https://stackoverflow.com/q/62840349/) and [here](https://stackoverflow.com/q/2895209/). My question was whether the pointer member and with that the whole containing structure may have a different size as all I could find out was that: "*All pointers to structure types shall have the same representation and alignment requirements as each other.*" as part of the shown quote. It affects my coding in a way to be safe to... – RobertS supports Monica Cellio Jul 11 '20 at 14:38
  • ...having the same constant size for the pointer member as well as the structure in whole regardless of the type of the structure the pointer is pointing to, so that I can use this technique without any doubts. I was hinted at my prev. question that I shall separate my concerns and decided to ask this question now in a bigger frame than to just incorporate "beside" another, which is indeed appropriate and better as this can be useful for others too, I guess, who maybe have a the same concern with regard to a similar problem. – RobertS supports Monica Cellio Jul 11 '20 at 14:43
  • 1
    Yes [it](https://stackoverflow.com/questions/62847600/is-the-size-of-an-object-equivalent-to-the-size-of-another-based-upon-the-same-a?noredirect=1#comment111142995_62847600) is OK. [Same presentation implies same size.](https://stackoverflow.com/a/62848190/2410359) for the member.If member has same alignment & representation, there's scant reason to expect a different `struct` size. I can see your desire for citation. Even if a struct member that is a struct pointer has the same representation/size/alignment needs as a substitute struct pointer, the concern of same struct sizeness is valid. – chux - Reinstate Monica Jul 11 '20 at 16:28
  • @EricPostpischil: How could a pointer to `int` not have the same size as a pointer to an array of `int`? The Standard specifies that the address of an `int` will behave like the address of an array of size 1 of `int`, and it specifies that adding 1 to the address of an `int` within an array will either yield a pointer to the next `int` (if any), or a pointer just past the end of the array. How could there not be a 1:1 correspondence between possible values of `int(*)[]` and those of `int*`? – supercat Jul 13 '20 at 14:58
  • @supercat: Re “The Standard specifies that the address of an `int` will behave like the address of an array of size 1 of `int`”: The passages regarding a pointer to an object not in an array behaving like a pointer to an element in an array of size 1 say they are “For the purposes of these operators,” which are the additive, relational, and equality operators, and the purposes are to specify the values produced by the operators. It has nothing to do with the representations of pointers. – Eric Postpischil Jul 13 '20 at 17:50
  • @EricPostpischil: Array-to-pointer decay means that lvalues of array type are implicitly converted into pointer-to-element type, so an `int*` has to be able to hold the starting address of any `int(*)[anyNumber]`, and be usable to access the first element of any such array. A contrived but conforming implementation might be allowed to do something wonky if code converts the address of an `int` into an `int(*)[1]`, but that's because the Standard makes no effort to forbid implementations from doing things that the Committee couldn't imagine any non-contrived implementation doing. – supercat Jul 13 '20 at 19:25
  • @supercat: There are no consequences from those statements that imply `int *` and `int (*)[anyNumber]` must be the same size. The fact that an `int *` must be able to represent a value equivalent to the value of any `int (*)[anyNumber]` merely implies an `int *` must have at least log2(n) bits, where n is the number of potential values of a `int (*)[anyNumber]`. It does not imply they must have the same representation of values or the same number of bits. – Eric Postpischil Jul 13 '20 at 20:17
  • @EricPostpischil: As noted, the Standard makes no attempt to forbid implementations from doing weird and wonky things the Committee couldn't imagine non-contrived implementations doing. While the Standard might be unclear as to whether "for the purposes of these operators" implies that a pointer value produced by adding 0 to the address of the first element of an `int[1]` would behave *fully* interchangeably with one produced by adding 0 to the address of an `int`, I don't think the authors of the Standard gave any thought whatsoever to the possibility of it doing otherwise. – supercat Jul 13 '20 at 20:25
  • @supercat: The address of the first element of an `int [1]` is an `int *`, and the address of an `int` is an `int *`, and both of these behave the same when zero is added because they are the same type. That has nothing to do with whether an `int *` must be the same size as an `int (*)[foo]`. – Eric Postpischil Jul 13 '20 at 20:28
  • @EricPostpischil: An `int*` which is produced by taking the address of the first element of an `int[1]` and adding 0 to it may be round-tripped through `int(*)[1]`. If an `int*` which is produced by adding 0 to the address of an `int` can be used in fully interchangeably with one produced from an array element's address, that would imply that it too could be round-tripped through `int(*)[1]`. One shouldn't read anything into the Standard's failure to explicitly *say* that absent evidence that the Committee didn't consider it so obvious as to not need stating. – supercat Jul 13 '20 at 20:32
  • @supercat: Please stop presenting arguments based on **values**. No argument about what values an `int *` and an `int (*)[foo]` must be able to represent can prove they must have the same size. – Eric Postpischil Jul 13 '20 at 20:38
  • @EricPostpischil: The Standard doesn't forbid implementations from using different representations for the pointer types, but it's not intended to invite everything it fails to forbid. There are lots of things that a contrived implementation might do to undermine its usefulness while still being "conforming". If nobody on the Committee could imagine any reason an implementation might benefit from doing something unusual, that would imply that anyone writing an implementation which could benefit from doing something unusual would be better placed than the Committee to judge... – supercat Jul 13 '20 at 20:45
  • ...the pros and cons of the unusual behavior versus the commonplace one, and it would be better to leave such issues to someone who can weigh the pros and cons than have them decided by a Committee that can't weigh such issues. – supercat Jul 13 '20 at 20:46
  • @supercat: Your comments are not relevant to what the standard says. The question is tagged language-lawyer, and your unsupported opinion that there is no good reason somebody might want different sizes for `int *` and `int (*)[foo]` are not relevant. – Eric Postpischil Jul 13 '20 at 21:26

2 Answers2

2

Two types having same presentation does not imply that the two types need to have same alignment requirements, though this is often true in practice.

The representation means that the similar object value is represented by the same bytes in the same order. Alignment tells what the address of the lowest byte in the type needs to be divisible by.

1

C 2018 clauses 6.2.6, entitled “Representations of types,” specifies representations of types. Paragraph 2 says:

Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.

From this, it is clear that a representation of an object is a sequence of bytes, and that sequence has some number of bytes, some order, and some encoding. So the number of bytes, the order of the bytes, and the encoding of the bytes is part of the representation. Therefore, if two objects have the same representation, they have the same number of bytes, the same order, and the same encoding.

Since they have the same number of bytes, they have the same size.

As an example, if an object X is represented with bytes A, B, and C, and object Y is represented with bytes A, B, C, and D, then X and Y do not have the same representation.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • So it is kind of `size == representation` if I understood correctly? "representation" seems to be used to describe the collection of all bytes needed to represent that type and so does the size. – RobertS supports Monica Cellio Jul 11 '20 at 12:48