开发者

Compatible types and structures in C

I have the following code:

int main(void)
{
    struct { int x; } a, b;
    struct { int x; } c;
    struct { int x; } *p;

    b = a;   /* OK */
    c = a;   /* Doesn't work */
    p = &a;  /* Doesn't work */

    return 0;
}

which fails to compile under GCC (3.4.6), with the following error:

test.c:8: error: incompatible types in assignment
test.c:9: warning: assignment from incompatible pointer type

Now, from what I understand (admittedly from the C99 standard), is that a and c should be compatible types, as they fulfill all the criteria in section 6.2.7, paragraph 1. I've tried compiling with std=c99, to no avail.

Presumably my interpretation of the standard is wrong?

Addendum

Incidentally, this question arises because I wanted to declare some template-like ma开发者_StackOverflow中文版cros to wrap various datatypes without the overhead of having to declare named types/typedefs everywhere, e.g. a trivial example:

#define LINKED_LIST(T)   \
    struct {             \
        T    *pHead;     \
        T    *pTail;     \
    }

...

LINKED_LIST(foo) list1;
LINKED_LIST(foo) list2;

...

LINKED_LIST(foo) *pList = &list1;  /* Doesn't work */


Looking at the draft specification I'm guessing you're relying on the conditions that come after the statement:

Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements ...

I think that the fact that these are all decared in the same C file means that they are in a single translation unit.

At a guess it would seem that this guarantees that when two C files include a header that declares a type then instances of that type will be compatible.


struct { int x; } is a anonymous structure tag, two anonymous structures cannot have "the same name", which is a necessary condition for type compatibility. You can declare types that are compatible with a non-anonymous structure using typedef.

struct tmp { int x; }; // declare structure tag
typedef struct tmp type1;
typedef struct tmp type2; // declare 3 types compatible with struct tmp
typedef struct tmp type3; // and with each other

type1 a, b;
type2 c;
type3 *p;
b = a;
c = a;
p = &a;


Compatibility of structures, unions, and enumerations

Within a single source file, each structure or union definition creates a new type that is neither the same as nor compatible with any other structure or union type. However, a type specifier that is a reference to a previously defined structure or union type is the same type. The tag associates the reference with the definition, and effectively acts as the type name. To illustrate this, only the types of structures j and k are compatible in this example:

struct   { int a; int b; } h;
struct   { int a; int b; } i;
struct S { int a; int b; } j;
struct S k;

Compatible structures may be assigned to each other.


Interestingly Clang gives the following:

error: incompatible type assigning 'struct <anonymous>', expected 'struct <anonymous>'

warning: incompatible pointer types assigning 'struct <anonymous> *', expected 'struct <anonymous> *'

It seems that if two (or more) anonymous structs are declared then the compiler does some internal magic which specifies which specific anonymous struct is being referred too.


Considering paragraphs 6.2.7 (compatible types) and 6.5.16.1 (assignment rules), I understand the same as you.

It seems that with your code GCC behave like if your struct definitions where tagged with different tags (which is not the case). In wich case types wouldn't be compatible ones. However it still looks like a gcc bug.

Any feedback from other compilers that implements C99 standard ?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜