0

N2479 C17..C2x working draft — February 5, 2020 ISO/IEC 9899:202x (E) (emphasis added):

6.7.2.1 Structure and union specifiers

17    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

18    The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

Question: what is the exact definition of suitably converted?

Extra: if there is no exact definition of suitably converted, then shall the C implementation document its understanding? For example (C/C++ preprocessor domain), Microsoft understands the term single item (C++, N4713) as single, permanently indivisible preprocessor token (which leads to issues while porting code from gcc/clang/other, which has different understanding), however, it seems that they don't document their understanding of the single item.

pmor
  • 5,392
  • 4
  • 17
  • 36
  • The intent is that if you have `struct foo { int x; ... }` then if you convert a `struct foo *` to an `int *` (say by casting) then it points to the `x` member of the corresponding `struct foo`. – Nate Eldredge Mar 19 '21 at 19:16
  • Is there a particular example of code for which you're not sure if it fits the definition or not? – Nate Eldredge Mar 19 '21 at 19:17
  • I think 90% of the questions you enter about C can be answered as “The C standard is not a formal mathematical/logical specification.” – Eric Postpischil Mar 19 '21 at 19:23

4 Answers4

3

In this context "suitable converted" means converted to a proper compatible type. For example:

#include <stdio.h>

struct mystruct {
    double a;
    int b;
};

int main()
{
    struct mystruct s = { 2.5, 4 };
    double *d = (double *)&s;
    printf("%f\n", *d);   // prints 2.500000
    return 0;
}

Here the first member of struct mystruct has type double. So a "suitable conversion" in this case means a struct mystruct * may be converted via explicit cast to double * and it will point to the a member.

dbush
  • 205,898
  • 23
  • 218
  • 273
3

This isn't a term with special meaning.

You are dealing with conversion from type A to type B. Type A is a pointer-to-structure type. Type B is not specified except that it must be suitable for use as a pointer to the initial member. Therefore, it must be a pointer (so we are dealing only with conversions between two pointer types) and it must follow the strict aliasing rule (the destination type can be pointer to a narrow character type, std::byte, the actual type of the first member, or a type that is representation compatible such as differing only in signedness).

Any pointer conversion that results in a suitable pointer satisfied "suitably converted".

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
2

Question: what is the exact definition of suitably converted?

The C standard does not give any “exact definition” of “suitably converted.”

I interpret it to mean any sequence of conversions to a type of “pointer to type of initial member” or “pointer to type of structure” such that the specifications of the conversions ensure the final pointer is pointing to the appropriate address. (E.g., has not passed through a conversion with possibly incorrect alignment.)

Extra: if there is no exact definition of suitably converted, then shall the C implementation document its understanding?

The C standard does not impose any requirement on a C implementation to document its understanding or interpretation of “suitably converted.”

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

It's not a formal term, but between the lines we can tell that it is used to mean a valid pointer conversion. And it needs to be carried out explicitly by the programmer by means of a cast.

In C, pretty much any object pointer can be converted to another object pointer casting. But what happens if you would de-reference such a pointer through the wrong type is a whole different story though. Most of the time it's poorly-defined behavior.

Valid pointer conversions in this case:

  • A pointer to a type compatible with the type of the first member.1) 2) 3)
  • A void pointer. 1) 2)
  • A pointer to character type.2)
  • A pointer to another structure type, where both structures are part of a union and share common initial member(s) of compatible type.4)

Optionally the pointer in any of the above cases can be type qualified. Unless the first member is a qualified type, in which case the pointer needs to share all qualifiers of that type. 1) 3)

1) The rules of simple assignment 6.5.16.1.
2) The rules regarding pointer conversions (6.3.2.3).
3) The rules of compatible type qualifiers (6.7.3).
4) The rule of common initial sequence (6.5.2.3).

The common initial sequence one is an oddball rule which apparently got poor compiler support, but it's in line with "strict aliasing".

Lundin
  • 195,001
  • 40
  • 254
  • 396