Same name structure with different definition in C - c

Is it allowed to use same name structure with different definitions in 2 different c files in the same project. For eg.
File1.c
typedef struct
{
unsigned int unVar;
} abc;
File2.c
typedef struct
{
int var;
} abc;
abc is used in both the files. When i compile these file as part of same project there are no errors, but i want to understand whether this is correct usage.

6.7.2.1 Structure and union specifiers
The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type,
within a translation unit.
Types are defined only within a translation unit, a .c file in this case.
There is no problem with defining two types with the same name in two different translation units.
However those two types are not compatible unless they follow the rules described in 6.2.7., p1. The types you defined are not compatible.

This is type definition. It is local for each .c file and there is no reason to get error. Definitions have to be made in header files and then you will not have such problem.

Symbols' names (variables', functions) must be unique within a translation unit.
A translation unit is a basic compilation unit for C and C++. It consists of a source file, along with all included files (either directly or indirectly).
In your case, you have two independent source files, each defining a struct; but they "can't see" each other, as they are within separate translation units.
You might get into trouble, however, during linking, if there are multiple symbols with the same name across target linking objects (as long as these symbols are exported, which can be modified with static keyword).

It is a correct usage to define two structs with the same name in two different *.c files because they are only valid for the current scope in the *.c where it is defined.
But further I would not recommend to do this to avoid any confusion of you and any other developer who has to work with two types of the same name that do doing other things.

Each definition is local to the file in which it appears. Since you compile the files separately, the compiler only sees one at a time. The linker binding the object files together does not verify type consistency, it only resolves symbols by name.
If you want to pass a st_localAscdData or a pointer to a st_localAscdData to a function from a different module, you must ensure consistency between the types declared in the different modules. This is the purpose of header files. Shared declarations belong in header files, that must be included in all modules that share a given type or function.
Global type consistency is not enforced by the C language, nor C++ to some extend, it is the programmers responsibility. Coding rules are guidelines to help programmers avoid pitfalls from this shortcoming.

You expect a redefined error (which will happen with cpp compiler) but it won't happen in C compiler.
This issue not just happen with structure but also with all kinds of variable.
I have make a question for this and have some detail and quality answer.
Does C have One Definition Rule like C++?

Related

What is and isn't available to linked files in C?

As of late, I've been trying to work through opaque pointers as a programming concept and one of the main things I've had difficulties with is figuring out what is or isn't available to other files. In a previous question, I failed in trying to create an opaque pointer to a struct and even though the answer explained how to fix that, I still don't quite understand where I went wrong.
I think that if a struct is defined in file2.c, file1.c can use it if both files include header.h which includes a declaration of the struct? That doesn't entirely make sense to me. header.h is used by both files, so I can see how they would access the stuff in it, but I don't understand how they would use it to access each other.
When I started programming, I thought it was pretty straight forwards, where you have program files, they can't access anything in each other, and those program files can #include header files with definitions and declarations in them (e.g. file1.c has access to variables/functions/etc. defined in header.h). Turns out I was wrong and things are quite a bit more complicated.
So from what I can tell, func() defined in header.h can be used by file1.c without being declared in file1.c, if file1.c includes header.h. As opposed to var defined in header.h which needs to be declared in file1.c with the extern keyword? And I think if var is defined in file2.c, file1.c can use it if it extern declares it, even if neither file1.c nor file2.c include header.h?
I apologize if the previous paragraphs makes no sense, I'm having quite a bit of difficulty with trying to describe something that confuses me. By all means, please edit this if you are able to fix mistakes or whatnot.
Books and webpages don't seem to help at all. They end up giving me misconceptions because I already don't understand something and draw the wrong conclusions, or they bring up concepts that throw me off even more.
What I'm looking what I'm looking for is an answer that lays this all down in front of me. For example 'this can access this under these circumstances', 'this cannot access this'.
Functions defined in one .c file can use anything defined in another .c file except for those things which are marked as static. Functions and global variables which are marked as static cannot be accessed from other translation units.
Whether something is declared in a header file or not doesn't really matter--you can declare functions locally in the same .c file which calls them if you want.
Your question asks about “access” at several points, but I do not think that is what you mean to use. Any object or function can be accessed (for an object: read or written, for a function: called) from anywhere as long as a pointer to it is provided in some way). I think what you mean to ask is what names are available.
Any declaration that is outside of a function is an external declaration. In this use of “external” in the C standard, it simply means outside of a function. (That includes a function declaration or definition; although it is declaring or defining a function, it is not inside itself or any other function declaration, so it is outside of any function.)
Any identifier for an object or function with an external declaration has either internal linkage or external linkage. If it is first declared with static, it has internal linkage (and may be later declared with extern, but that will not change the linkage). Otherwise, it has external linkage.
Any identifier with external linkage will refer to the same object or function in all translation units (provided other rules of the C standard are satisfied—a program can do various things that will result in behavior not defined by the C standard).
Thus your answer is: The name of any object or function that is (a) defined outside of any function and (b) not initially declared with static is available to be linked to from other translation units.
Some technicalities that may be of interested:
What people think of as a variable is two things: an identifier (the name) and an object (a region of memory that stores the value).
Identifiers have scope, which is where they are visible in the source code. Identifiers declared outside functions have file scope; they are visible for the rest of the translation unit. Identifiers declared inside functions have various other types of scope: function scope, function prototype scope, and block scope.
You may sometimes seem people refer to global scope or external scope, but these are misnomers; they are not terms used in the C standard.
Linkage is related to scope and is sometimes confused with it, but linkage is a different concept: Two identical identifiers declared in different places can be made to refer to the same thing. Those identifiers have different scopes, notably one having file scope in one translation unit and the other having file scope in a different translation unit. Since each translation unit is compiled separately, the compiler generates code regarding each identifier separately. When the object modules are linked, then the code is bounded together, causing the separate identifiers to refer to the same object or function.
Identifiers can be declared with extern inside functions, but these can only link to objects or functions defined elsewhere; external definitions cannot appear inside functions.

C compiler ignores 'static' for declaration of struct

In C, if I declare a structure like so:
static struct thing {
int number;
};
and compile it (with gcc in this case), the compiler prints this warning:
warning: 'static' ignored on this declaration
[-Wmissing-declarations]
Why is this?
My intention in making the struct static would be to keep thing out of the global namespace so that another file could declare its own thing if it wanted.
You cant define the storage without defining the actual object.
static struct thing {
int number;
}obj1,obj2;
is ok and:
struct thing {
int number;
};
static struct thing x,y;
Struct tags (and typedef names) have no linkage, which means they are not shared across translation units. You might use the term "private" to describe this. It is perfectly fine for two different units to define their own struct thing.
There would only be a problem if it was attempted to make a cross-unit call of a function with external linkage that accepts a struct thing or type derived from that. You can minimize the chance of this happening by ensuring that functions with external linkage are only called via prototypes in header files (i.e. don't use local prototypes).
You can't use static on this way to control the linkage of a type like you could for a function or object, because in C types never have linkage anyway.
"Global namespace" isn't quite the term you want here. C describes names of objects and functions as having "external linkage" if the same name can be declared in different translation units to mean the same thing (like the default for functions), "internal linkage" if the same name can be redeclared within the same translation unit to mean the same thing (like declarations marked static), or "no linkage" when a declaration names a different object or function from any other declaration (like variables defined within a function body). (A translation unit, roughly speaking, is one *.c file together with the contents of the headers it includes.) But none of this applies to types.
So if you want to use a struct type that's essentially private to one source file, just define it within that source file. Then you don't need to worry about another usage of the same name colliding with yours, unless maybe somebody adds it to a header file that the source file was including.
(And just in case a C++ user comes across this Q&A, note the rules for this in C++ are very different.)

Do all C functions need to be declared in a header file

Do I need to declare all functions I use in a .c file in a header file, or can I just declare and define right there in the .c file? If so, does a definition in the .c file in this case count as the declaration also?
Do I need to declare all functions I use in a .c file in a header file,
or can I just declare and define right there in the .c file?
You used "use" in the first question and "define" in the next question. There is a difference.
void foo()
{
bar(10);
}
Here, foo is defined and bar is used. You should declare bar. If you don't declare bar, the compiler makes assumptions about its return type.
You can declare bar in the .c file or add the declaration in a .h file and #include the .h file in the .c file. Whether you use the first method or the second method is up to you. If you use the declaration in more than one .c file, it is better to put that in a .h file.
You can define foo without a declaration.
If so, does a definition in the .c file in this case count as the declaration also?
Every function definition counts as a declaration too.
For the compiler, it does not matter if a declaration occurs in a .h or a .c file, because the compiler sees the preprocessed form.
For the human developer reading and contributing to your code, it is much better (to avoid copy&pasting the same declaration twice) to put the declaration of any function used in more than one translation unit (i.e. .c file) in some #include-d header.
And you can define a function before using it.
BTW, you might even avoid declaring a function that you are calling (it defaults to returning int for legacy purposes), but this is poor taste and obsolete way of coding (and most compilers can emit a warning in that case).
No, it is not necessary.
The reason of the header files is to separate the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the .c file defines "how" it will perform those features.
This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.
The answer to both questions is yes. You can declare c-functions in both header and .c file. Same with definition. However, if you are defining it in header file, you may have slight problems during compilation.
By default functions have external linkage. It means that it is supposed that functions potentially will be used in several compilation units.
However sometimes some auxiliary functions that form implementations of other functions are not designed to be used in numerous compilation units. Such functions declared with keyword static have internal linkage.
Usually they are declared and defined inside some .c module and are not visible in other compilation units.
One occasion that requires functions to be declared in a separate header is when one is creating a library for other developers to use. Some libraries are distributed as closed source and they are provided to you as a library file (*.dll / *.so ...) and a header.
The header file would contain declarations of all publicly accessible functions and definitions of all publicly required structures, enums and datatypes etc.
Without this header file the 3rd party library user would not know how to interface with the library file and thus would not be able to link against it.
But for small, trivial C programs that are not intended for use by other people, no you can just dump everything into a C file and build it. Although you might curse yourself years later when you need to maintain that code :)

Why won't C compile if two separate source files in the same workspace share function names?

I'm using eclipse indigo, gcc and cdt in a project. If two functions in separate source files share names (regardless of return type or parameters), eclipse flags a redefinition error. This isn't a huge issue regarding this project given I can easily rename these functions, and I'm well aware of wrappers if it were. Although this isn't a critical issue, it does make me think I'm not understanding the c build process. What occurs during the build process in which a program structure like this would cause issue?
Here's some more info. on the situation, and where my understanding is so far -- not necessary to answer the question, although there must be a hole in my understanding.
In this case, the two functions are intended to be used only locally, as such their prototypes are not given in the .h interface, and for the sake of my point, neither are defined 'static'.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units. With that in consideration, I would have assumed that the neither source file is aware of the presence of the other, and the compiler would have no problem indexing the two functions, as the separate files would allow for proper distinguishing between the two during linking -- so long as they weren't included in the same compilation unit.
I noticed that statically defining either instance of the function declaration removes the error. I remember reading at some point that every function not declared static is global -- although given these functions are not a part of the .h interface, the practical example in which including the .h interface doesn't allow for the including program to reference all .c functions would indicate "hiding" these functions would be of no issue.
What am I overlooking?
Some insight would be greatly appreciated, thanks!
This is the concept of "linkage". Every function and variable in C has a linkage type, one of "external", "internal", and "none". (Only variables can have no linkage.)
Functions have external linkage by default, which means that they can be called by name from any compilation unit (where "compilation unit" roughly means one source file and all the headers it includes). This can be expressed explicitly by declaring them extern, or it can be overridden by declaring them static. Functions declared static have internal linkage, meaning they can be referenced by name only from other functions in the same compilation unit.
No two external functions anywhere in the same program can have the same name, regardless of header files, but static functions in different compilation units may have the same name. A static function may have the same name as an external function, too -- then the name resolves to the static function within its compilation unit, and to the external function elsewhere. These restrictions make sense, for otherwise it would be possible for a function call to be ambiguous.
Header files don't factor into the linkage equation at all. They are primarily a vehicle for sharing declarations, but a function's linkage depends only on how it is declared, not on where.
I leave discussion of variables' linkage for another time.
It doesn't matter whether one source module includes headers for another. Header files only contain declarations for the purpose of local functions being able to find functions in other modules. It doesn't mean that functions not declared don't exist from the perspective of that module.
When everything gets linked together, anything not specifically defined to be local to one source module (i.e. static) has to have a unique name across all linked components.
remember reading at some point that every function not declared static is global
Having understood this you got the main point and reason for the behaviour observed.
.h files are not known to the linker, after pre-processing there are only translation units left (typically a .c file with all includes merged in), from which .o files are compiled.
There are no interfaces on language level in C.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units.
Declare those functions as static. This is the only way to "hide" a function from the linker "inside" a translation unit.
C doesn't "mangle" function names the way C++ or Java do (since C doesn't support function polymorphism).
For example, in C++, the functions
void foo( void );
void foo( int x );
void foo( int x, double y );
have their names "mangled" into the unique symbols1
_Z3fooid
_Z3fooi
_Z3foov
which is how overloaded function/method calls are disambiguated at the machine level.
C doesn't do that; instead, the linker sees two different function definitions using the same symbol and yaks because it has no way to disambiguate the two.
1. This is what happens on my system, anyway

Why not just declare structs in headers? Wouldn't this make include-guards unnecessary?

I recently realized that while it is illegal to ever define something more than once in a given translation unit, it is perfectly legal to declare things (functions, variables, structs) as many times as you like. I was under the impression that the purpose of include guards was to prevent duplicate declarations.
In fact, their purpose seems to be to prevent duplicate definitions. However, since function and variable definitions properly belong in .c files and not .h files and only .h files are #include'd, this would seem to imply that only structs and unions present a problem (because we typically define them in .h files, not just declare them). (Even the example on the wikipedia page on include guards uses struct definitions).
My question is: why is it so common to define structs in header files? Couldn't we just declare them in header files and then put their definitions in .c files and then include guards would be completely unnecessary since duplicate declarations are okay?
If I had to guess, it's because if we did this, the only thing that source files that include such header files would be able to so is create pointers to the structs since the definition of what fields they contain is in some other .c file. Is that accurate?
In order to meaningfully use a struct type, i.e in order to be able to access its contents, to define objects of that struct type, to know the size of that struct type you have to define that struct type. The definition has to be visible in every translation unit in which you want to use the struct type as mentioned above. This is the reason you'd want to define struct types in header files.
If you just declare struct types in header files, you won't be able to do any of that. The only thing you can do with declared (but not defined) struct type is declare pointers to that struct type. That is a valuable auxiliary feature, but by itself it is completely useless.
As an additional note, include guards are not just for preventing multiple definitions of struct types. C language also prohibits repetitive typedef declarations (C++ notably allows them), repetitive static function definitions, repetitive static variable definitions, repetitive macro definitions, repetitive enum definitions and probably something else as well.
But you are right, if your header file only contains declarations that can be legally repeated in the same translation unit, then formally you don't need include guards in that header file.
OP:My question is: why is it so common to define structs in header files?
Structure that are used by multiple .c files need to share the same definition and so are in .h files.
Structures that are local to a single .c file (making them effectively "static" or of local scope) should be declared in the .c file and not in the paired .h file.
Include guards are needed in this context for maintenance. As OP says, the structure definition could be in .c files and shared that way (being the same), but that imposes a maintenance nightmare. Declare/define shared structures +once_ and then one can maintain them in one place.

Resources