Incompatible types of structures in casts / assignments?

This is a continuation of this issue .

I am trying to avoid using an explicit typedef to copy one array to another using such as:

#include <stdio.h>

int main(void)
{
  int i;
  int dst[] = { 10, 20, 30 }, src[] = { 1, 2, 3 };

  *(struct{int _[3];}*)dst = *(struct{int _[3];}*)src;

  for (i = 0; i < 3; i++) printf("%d\n", dst[i]);
  return 0;
}

I get with gcc arrcpy.c:8: error: incompatible types in assignment, however with Open Watcom it compiles fine (and works as I expect, printing 1 to 3).

Is gcc behavior standard or not? If so, which chapter and section? I cannot understand why two identical type definitions struct{int _[3];}do not match (or are compatible) in gcc eyes.

EDIT . I know this is a bad coding style. The question is different. I am curious if there is a rationale for gcc behavior, if it is legal.

+5
4

gcc , . , , . , typedef.

+6

memcpy?

#include <stdio.h>
#include <string.h>

int main(void)
{
  int i;
  int dst[] = { 10, 20, 30 }, src[] = { 1, 2, 3 };

  memcpy(dst, src, 3 * sizeof(int));

  for (i = 0; i < 3; i++) printf("%d\n", dst[i]);
  return 0;
}

3: sizeof(dst)/sizeof(dst[0])

EDIT: , , outis ', , . , , .

+1

, structural C. C .

§ 6.7.2.1-7 C99:

struct-declaration-list struct-or-union-specifier . struct-declaration-list . struct-declaration-list , undefined. , }, .

struct-declaration-list struct-or-union-specifier C (§ 6.7.2.1):

struct-or-union-specifier:
    struct-or-union identifieropt { struct-declaration-list }

struct-or-union:
    struct
    union

, .

, , .

#include <stdio.h>

int main(void) {
    // struct T is only visible in main()
    struct T {int _[3];};
    int i;
    int dst[] = { 10, 20, 30 }, src[] = { 1, 2, 3 };

    *(struct T*)dst = *(struct T*)src;

    for (i = 0; i < 3; i++) printf("%d\n", dst[i]);

    return 0;
}

void fails(void) {
    // will cause a compilation error, because struct T is an incomplete type.
    struct T t;
}
+1

struct :

C99 6.2.7:

, . 6.7.2 , 6.7.3 6.7.5 . , , , . ...

Types do not match. If they were declared in separate translation units, they would be compatible, however.

However, even if they were compatible, your code will cause undefined behavior for at least two reasons:

  • It uses the name "_", which is reserved.
  • Access to objects as a different type (except for structures using pointers, unions, etc. char) is not allowed.
+1
source

All Articles