开发者

Why do structure definitions have internal linkage?

(I am talking about C, but it also applies to class templates in C++)

In header file, it is a custom to put all the DECLARATIONS, not definitions. However, we usually put structure definitions or class templates in header file as well without actually knowing why we can. This doesn't really make sense because they are definitions as well -- ONE DEFINITION RULE. (Yes, structure definitions and class templates don't cause any storage to set, but you still get "redefinition" error below which implies that they are definitions).

EX) defining multiple structures with same tag within same file give you a redefinition error, but defining multiple structures with same tag in multiple source files don't cause any error (same thing happens with class).

The only thing that makes sense is that structure definitions and class templates have internal linkage (opposed to default external linkage), but I can't find any references about it in K&R or reference manual. In fact, structures are not even mentioned in linkage.

I want to know the exact reference where ANSI standard points out this pheonomenon. (IMO, this is a pretty ambiguous thing which HAS TO be mentioned in ANSI standard somewhere).


ED开发者_StackOverflowIT I am NOT asking why structure definitions can be put into the header file.

I am asking why putting structure definition in header file won't cause redefinition error like it does when we put variable definitions in header file (and include it in multiple source files)

EX) test1.c: int a = 3; test2.c: int a = 4; Causes compile error because of redefinition. However,

test1.c: struct test { int a }; test2.c: struct test { int b }; Does not cause compile error, and the only reason I can come up with is that structure definitions either have internal linkage, or no linkage at all.


In C only objects and functions have linkage. Since struct in C may not contain functions or "static" member objects as in C++ your question makes not much sense, here.

Member functions in C++ as long as they are not defined but only declared inside the struct pose no problem. If they are also defined, they are inline. The concept of inline was just invented for C++ to capture that case: a function definition that can be shared through a header file in several compilation units. C99 that adopted that concept (modifying it slightly).

static member objects pose indeed more of a problem. The syntax on how to instantiate these guys is quite obscure, especially for template classes or structs. If you'd like to know about that one you'd have to ask for that, tagged specifically with C++.


Structures are defined in a header file because the header file provides the interface to a module. When the structure is defined in the interface, it is possible for the users of the interface to:

  • refer to the members of the structure
  • know how large the structure is - otherwise they couldn't allocate memory for the structure

Linkage has nothing to do with it - only functions are linked, not the data structures.

Note that you can still declare a structure in a header file, which is useful if you want to hide the internals of the structure (opaque data structure). Users of the interface can have pointers to the structure and use them as kind of a cookie, but they cannot allocate such a structure themselves, or "see" inside it.

As for not getting a redefinition error when defining a structure in a header file, that's simply because of header guards - a header typically looks like this:

#ifdef MYHEADER_H
#define MYHEADER_H

struct a { int x; }
void f(void);
/* and so on */

#endif

So when including a header file, it is usually included only once and therefore the structure is only defined once per translation file. The linker has nothing to do with the structure definitions as they have no linkage.


The struct line is merely a definition. The definition is not visible outside of the source file.
FYI: Neither source file exports anything.

To test this:

$ cat test1.c
struct test { char a; };
$ gcc -o test1.o -c test1.c
$ nm 
$ echo "struct test foo; " >> test1.c
$ gcc -o test1.o -c test1.c
$ nm
0000000000000001 C _foo


I think you are mixing yourself up a bit here, you can put whatever you like in a header file.

The usual things to put in them are declarations of enums, typedefs, structs, and function prototypes so various C files can compile without having to have knowledge of the actual function or actual memory ( a struct basically is definition of how memory is laid out )


I don't have a copy of a final version, but from the n843 draft of the specification I see:

from 6.7.2.3 Tags: "4 Two declarations of structure, union, or enumerated types which are in different scopes or use different tags declare distinct types. Each declaration of a structure, union, or enumerated type which does not include a tag declares a distinct type."

from 6.2.1 Scopes of Identifiers: "4 Every other identifier has scope determined by the placement of its declaration (in a declarator or type specifier). If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit. [...]" [emphasis in original] (The only identifier type that I see mentioned in this section prior to this statement was labels, which have function scope.)

I'm no expert on C or the standards, but it looks to me like this explains the behavior you are seeing. So, a struct should have a collision if the file scope is the same and the struct has a duplicate tag, because having a distinct tag would be required to make them distinct types. But if they are in a different file scope, there's no problem, because as long as they are in different scopes, the requirements are met for being a distinct type.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜