If i have a header file in which i declare and define a function, and i include the header in a source file, will it return an error? and if yes which one?
I tried doing it and it worked but when someone else tried it on his PC, it didn't.
so in which step did the problem occur? is it the pre-processing or linking part?
If I define the same function twice (twice in the source file or once in the header and another in the source), what type of error is that?
I need to know it for an exam but couldn't find answers myself
I think you should first gather some information about the subject
of linkage.
Then you should do some research on header file descriptions.
Finally, you should learn the undefined behavior.
Linkage
Linkage 2
Header File Create
Undefined Behavior / UB
If i have a header file in which i declare and define a function, and i include the header in a source file, will it return an error? and if yes which one? I tried doing it and it worked but when someone else tried it on his PC, it didn't. so in which step did the problem occur? is it the pre-processing or linking part?
It depends. If you don't have any include guards around the function definition and the file gets #included more than once within the same translation unit, or if the name of the function defined in the header conflicts with another variable or function name defined elsewhere in the source, then yes you'll get some kind of duplicate or conflicting definition error. If nothing in the header conflicts with other code, you won't. Without knowing the details of your code or your friend's code, there's really no way to answer definitively.
Short answer is "don't do that" - don't put function or variable definitions in header files. That way you avoid this kind of problem completely.
If I define the same function twice (twice in the source file or once in the header and another in the source), what type of error is that? I need to know it for an exam but couldn't find answers myself
Most compilers call it a "duplicate definition" error. There's no formally defined name for it. Here's the relevant text from the C language definition:
6.9 External definitions
...
Constraints
...
3 There shall be no more than one external definition for each identifier declared with
internal linkage in a translation unit. Moreover, if an identifier declared with internal
linkage is used in an expression (other than as a part of the operand of a sizeof or
_Alignof operator whose result is an integer constant), there shall be exactly one
external definition for the identifier in the translation unit.
...
Semantics
...
5 An external definition is an external declaration that is also a definition of a function
(other than an inline definition) or an object. If an identifier declared with external
linkage is used in an expression (other than as part of the operand of a sizeof or
_Alignof operator whose result is an integer constant), somewhere in the entire
program there shall be exactly one external definition for the identifier; otherwise, there
shall be no more than one.161)
161) Thus, if an identifier declared with external linkage is not used in an expression, there need be no
external definition for it.
C 2011 Online Draft
The rule of thumb - do not place any code (ie function definitions) or variable definitions in the header files.
There are some possible exception (for example static inline functions).
Header files:
Function dclariations, type declaration and extern object definitions.
Source files:
Function bodies and data definitions.
Related
0.c
int i = 5;
int main(){
return i;
}
1.c
int i;
Above compiles fine with gcc 0.c 1.c without any link errors about multiple definitions. The reason is i gets generated as common blocks (-fcommon which is the default behaviour in gcc).
The proper way to do this is using the extern keyword which is missing here.
I have been searching online to see if this is undefined behaviour or not, some post say it is, some say it isn't and it's very confusing:
It is UB
Is having multiple tentative definitions in separate files undefined behaviour?
Why can I define a variable twice in C?
How do I use extern to share variables between source files?
http://port70.net/~nsz/c/c11/n1570.html#J.2
An identifier with external linkage is used, but in the program there does not exist exactly one external definition for the identifier, or the identifier is not used and there exist multiple external definitions for the identifier (6.9).
It is NOT UB
Global variables and the .data section
Defining an extern variable in multiple files in C
Does C have One Definition Rule like C++?
Look for -fno-common:
https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Code-Gen-Options.html
So which one is it? is using -fcommon one of the few places where having multiple definition is allowed and the compiler sorts it out for you? or it is still UB?
Analysis of the code according to the C Standard
This is covered in section 6.9/5 of the latest C Standard:
Semantics
An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the
identifier; otherwise, there shall be no more than one.
The term "external definition" should not be confused with "external linkage" or the extern keyword, those are are entirely different concepts that happen to have similar spelling.
"external definition" means a definition that is not tentative, and not inside a function.
Regarding tentative definition, ths is covered by 6.9.2/2:
A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static , constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.
So in your file 1.c, as per 6.9.2/2 the behaviour is exactly as if it had said int i = 0; instead. Which would be an external definition. This means 0.c and 1.c both behave as if they had external definitions which violates the rule 6.9/5 saying there shall be no more than one external definition.
Violating a semantic rule means the behaviour is undefined with no diagnostic required.
Explanation of what "undefined behaviour" means
See also: Undefined, unspecified and implementation-defined behavior
In case it is unclear, the C Standard saying "the behaviour is undefined" means that the C Standard does not define the behaviour. The same code built on different conforming implementations (or rebuilt on the same conforming implementation) may behave differently, including rejecting the program , accepting it, or any other outcome you might imagine.
(Note - some programs can have the defined-ness of their behaviour depend on runtime conditions; those programs cannot be rejected at compile-time and must behave as specified unless the condition occurs that causes the behaviour to be undefined. But that does not apply to the program in this question since all possible executions would encounter the violation of 6.9/5).
Compiler vendors may or may not provide stable and/or documented behaviour for cases where the C Standard does not define the behaviour.
For the code in your question it is common (ha ha) for compiler vendors to provide reliable behaviour ; this is documented in a non-normative Annex J.5.11 to the Standard:
J.5 Common extensions
J.5.11 Multiple external definitions
1 There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern ; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).
It seems the gcc compiler implements this extension if -fcommon switch is provided, and disables it if -fno-common is provided (and the default setting may vary between compiler versions).
Footnote: I intentionally avoid using the word "defined" in relation to behaviour that is not defined by the C Standard as it seems to me that is one of the cause of confusion for OP.
In a C program, what are the valid places where I can include the header file #include <stdio.h>?
I mean, generally, we include the header files at the beginning of the C program but if I include it inside the main() function before any printf or fprintf function is used, will it give the same result as before or will it give any error?
Also, if such a declaration works fine, then what are the other places where I can declare this header file except at the beginning of the program?
The standard C headers must be included outside of any function or declaration — at file scope. Otherwise, they merely need to be included before their content is used.
C11 §7.1.2 Standard headers ¶4:
Standard headers may be included in any order; each may be included more than once in a given scope, with no effect different from being included only once, except that the effect of including <assert.h> depends on the definition of NDEBUG (see 7.2). If used, a header shall be included outside of any external declaration or definition, and it shall first be included before the first reference to any of the functions or objects it declares, or to any of the types or macros it defines. However, if an identifier is declared or defined in more than one header, the second and subsequent associated headers may be included after the initial reference to the identifier. The program shall not have any macros with names lexically identical to keywords currently defined prior to the inclusion of the header or when any macro defined in the header is expanded.
File scope means 'not inside a function or variable declaration, nor inside a struct or union declaration, or inside a typedef, etc. For a formal definition, see C11 §6.2.1 Scopes of identifiers ¶4:
… 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. …
Note that other headers from standards such as POSIX typically impose similar rules about where they can be included — they must be included at file scope.
However, other headers that are defined by users may be included wherever the programmer deems fit, subject to the included material leaving a syntactically valid translation unit (TU).
For example, there are "X-Macros" which often involve including a header multiple times in a single TU with different effects each time, and the #include line can appear in the middle of a variable's initializer if that's the intended usage (and with X-Macros, it often is the intended usage).
static struct WhatEver data[] =
{
// #include <stdio.h> // Incorrect
#include "xmacro.h" // Possibly correct
};
It is a good practice to include all the header files at the start of program.
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.
I apologize if this is a beginner's question, but after working in C for a bit, I finally would like a bit of clarification on exactly what kind of files/functions are available to a function.
I understand we can explicitly include other files with the #include macro like so:
#include bar.c
But what about files that are in the same directory? Let's say we have the following file structure:
src-
|
a.c
b.c
And let's say a.c has the function "foo()" and b.c has "bar()"
Would I be able to call bar() within a.c even without explicitly including b.c in the header file?
And what about in sub-directories such as the following:
src-
|
a.c
|
someFolder-
|
b.c
Would I still be able to access bar() in a.c?
Basically, how exactly is the scope of functions (without including them in headers) defined?
You are confusing scope with linkage.
The term scope descibes if an identifier is visible to the compiler in a given context. The broadest scope known to the C language is file scope which means that the identifier is visible from the point it is declared to the end of the translation unit after preprocessing. You can make any identifier visible/known by declaring it, but making an identifier visible does not mean that refering to the identifier refers to the thing it refers to in another file.
The term linkage describes how two identifiers refer to the same thing. There are three levels of linkage: with no linkage, each identifier with the name refers to a different thing. With internal linkage, each identifier within the same translation unit refers to the same thing. With external linkage, each identifier in the whol program refers to the same thing. For two identifiers in two translation units to refer to the same thing, you need to declare both of them to have external linkage.
This is independent of how the declaration is obtained. There is no difference in writing int foo() in a common header file to writing the same line in both source files. In either case, all identifiers refer to the same foo() as functions have external linkage unless explicitly declared to have internal linkage with the static type specifier.
It is also independent of how your source code is laid out. As long as all translation units are linked into the same binary, you can call all functions with external linkage in each translation unit.
Depends on whether you are linking these into one binary or not.
If linking - then yes, functions can be called with implicit declaration.
Common pattern in this case is making a header(s) file with all declarations, including *.c files is usually not preferred, since #include is just textual inclusion of file contents
#include (a preprocessor directive, not a macro, BTW) has a configurable list of directories it searches.
If you use the #include "something.h" form (as compared to the angle bracket form for including system headers), the first directory in the list is the directory of the including file.
Although #include does a simple textual inclusion so it is technically possible to include any text file, c files are almost never included.
In C, you usually compile c files separately into object files and link them together, and what you do include is header files which consist of declarations, which represent interfaces of the other object files which your current compilation unit otherwise wouldn't see.
Check out http://www.cs.bu.edu/teaching/c/separate-compilation/ or another article on that topic.
The forward slash "/" should work in this case.
If you can include foo.h without problem, this means the directory (say, C:\DIRFOO) is predefined in the "include" directive of the compiler. So, another file (say bar.h) in a sub directory (say, C:\DIRFOO\DIRBAR) can be included via #include <DIRBAR/bar.h>.
I tried different websites but I don't get it. Could you explain it in simple english?
"scope" is a namespace of the compiler;
"linkage" is about compiled units.
I explain a bit more: A variable declared in a function has the scope of that function, i.e. it is visible only within that function. A variable declared as static in a source file, can be seen only by the code in that source file (and all included files!). Variables can also have global scope: they can be referred to in a source file, but not declared (allocated) in that source file but declared in another source file.
In stead of "source file" we should say "compilation unit" as it is the C source file being compiled, plus all included files. Scope refers to everything the compiler can "see" in a compilation unit. These are namespaces.
After compilation of a project there are a number of object files, one for each compile unit. Each may refer to variables used that are not declared in the compile unit. The linker must now resolve these references between object files: linkage.
This also holds for functions.
Keep reading on your page (http://msdn.microsoft.com/en-us/library/teta4z44.aspx). This is talking about visibility of objects between translation units (source files). It first talks about "internal linkage": objects defined as static, unique to the translation unit but available throughout.
Next it talks about "external linkage": a like-level object not declared static. These are shared between translation units.
Finally, "no linkage": an object such as a variable within a function, not declared extern, which is unique to that scope.
If you follow the links on the bottom of the page, it's all explained.
Share what I learned about this issue.
Scope is for the benefit of the compiler, while linkage is for the benefit of the linker.
The compiler uses the scope of an identifier to determine whether or not it's legal to refer to the identifier at a given point in a file. When the compiler translate a source file into object code, it notes which names have external linkage, eventually storing these names in a table inside the object file.
Thus, the linker has access to names with external linkage; names with internal linkage or no linkage are invisible to linker.
(The above text is from book "C programming: A modern approach", which contains an exactly same question).