I have method in header file to which I added static keyword. e.g.
static int32_t Tlvlist_AddRawt(Tlvlist *a, uint8_t type, uint16_t size, const void *bytes);
The method is implemented in .c file where the static
keyword is not present in function name.
This method is called from another function of same .c file.
The later function (which uses this static function) is also called from main.
But I get warning: "Unused function 'Tlvlist_AddRawt'" in the header file.
Why would this happen?
ps. I use Xcode.
When you mark a function declaration static, it is not visible outside the translation unit in which it appears. But also, it represents a different function in every translation unit in which it appears. As such, it is rarely a good idea to use static in a header file, because then you're declaring a separate function in each C source that includes the header.
The compiler diagnostic is telling you that there is at least one C file that includes your header but does not provide a definition of Tlvlist_AddRawt() to go with the declaration from the header.
If you want to declare a static function separately from its definition -- for instance to prototype it for other functions that appear earlier in the source file -- then put the declaration in at the top of the C source file in which its body appears instead of in a header. Putting it in a header is counterproductive.
You never declare static functions in a header file intended for use in other modules, because the purpose behind making a function static is "hiding" it from users outside your modules. Static C functions are visible only inside the translation unit* where they are defined. When a function is declared static, but no other functions from the same translation unit use it, you get the "unused static" warning.
If you would like to define a function in one file, and use it from another file, you need to put its forward declaration in a header, include that header from both translation units, and link the translation results together. Removing the static keyword from the header should address this problem.
* Translation Unit is a fancy name for a .c file.
Related
I am reading through Linux v3.19's implementation of PID namespaces and in pid_namespace.h there are functions defined that are redefined in pid_namespace.c. For example, in pid_namespace.h there is the following definition:
static inline struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *ns)
{
if (flags & CLONE_NEWPID)
ns = ERR_PTR(-EINVAL);
return ns;
}
And then in pid_namespace.c there is a second copy_pid_ns definition:
struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *old_ns)
{
if (!(flags & CLONE_NEWPID))
return get_pid_ns(old_ns);
if (task_active_pid_ns(current) != old_ns)
return ERR_PTR(-EINVAL);
return create_pid_namespace(user_ns, old_ns);
}
What does this re-defining achieve? Why is it done? Thanks for your help!
These two definitions corresponds to two incompatible configurations:
Definition of copy_pid_ns in the include/linux/pid_namespace.h#L76 header is parsed only with CONFIG_PID_NS option disabled (see line 68 in that header).
The file kernel/pid_namespace.c is compiled only with CONFIG_PID_NS option enabled (it can be found from kernel/Makefile). For that configuration the header contains just a declaration of the function at line 62.
Situation when the header file declares some function twice is quite natural for the Linux kernel sources:
One declaration (without definition) corresponds to some functionality being enabled. In that configuration the function is defined in some source file which is compiled only with functionality being enabled.
Another declaration is a definition of static inline function and corresponds to disabled functionality.
Note
The question omits relevant information from the source code repository it extracted the source code from, so the answer below does not apply to the source code in those files. It appears at most one of the two definitions is selected based on build options, so they are not both used in the same build.
Old Answer Regarding static inline
The version in the header is marked static inline. In this declaration, static causes the name copy_pid_ns to have internal linkage, meaning the definition here will apply only to uses of copy_pid_ns in the current translation unit (the source file being compiled, including the files it includes). The idea of inline is that this function is so small, it would be good if, wherever it is called, the compiler just wrote the code for it in place of the call instead of actually using a subroutine call instruction for the function. (Technically inline is just a suggestion to the compiler in this regard. Good modern compilers mostly make their own decisions about which functions to inline.)
Because the definition in the header is static inline, it is not accessible to other translation units. The definition in the other source file has external linkage, meaning any uses of copy_pid_ns in other translation units can be linked to it (if they do not have their own private static version). Those uses in other translation units will have to use actual subroutine call instructions to call this function.
Providing an external version is not necessary if all uses of copy_pid_ns have the static version available, but one may be provided because that is not always the case or just as a safety fallback.
First look at qualifiers in front of the function:
static inline... -> static will be resolved only in included source files (*.c, *.cpp)
like private qualifier, inline will replace directly this function instead accessing it as reference
have no qualifiers -> more like a public external function. If you define your usage of the function as extern you should compile (*.c) file which contains implementation of the function and then the linker will resolve your call to the function as reference.
It's not a redefinition. The key to realizing what's intended here is the presence of static qualifier for the first definition, and knowing how programs are built with C. Also, inline is seldom used without static, at least with C89 and GNU extensions which is what is used to compile Linux, but inline in and out of itself doesn't play a role here.
The static inline definition in pid_namespace.h is only visible to the translation unit (.c file) that includes that header file, directly or indirectly. The static qualifier is what restricts this visibility. If you include pid_namespace.h from another translation unit, that translation unit will have its own, another copy of the function. Each object file will have its own copy of the function definition, available only to itself. Additionally, because of the inline qualifier, the function may not even exist as such because the compiler is free to "inline" it.
The second definition does not have a static qualifier and can thus be used by other translation units that do not themselves contain it. The C compiler compiles object files from their respective translation units, and the linker links these object files together and produces a program image where references to said definition are correctly resolved. The compiler does not care if more than one translation unit embed the same function -- to it they're just object files it needs to compile one by one. But the linker will abort because it isn't designed to have to choose between such multiple definitions in its input.
In practice, there is many ways this can be used. The former definition may be the short version used in kernel mode (privileged kernel code), while the latter is used in user mode, as result of processing a system call, for example.
In general, defining procedures several times is permitted as long as there is at most one object available to the linker (in case it needs to resolve references to the function, like function calls). You can juggle your .c and .h files however you like, as long as that requirement holds. If you also know how to use static and inline qualifiers, you can add definitions that are not externally visible (static) and benefit from compiler being able to inline them.
Is there a case when a function can be defined within a header file? I was told by person whose opinion I respect that there are cases when a function can be defined in a header file included by multiple C source files. However, I could not find any. Just confirm, I define the function in-line in a header file but that also did not work. I will but have not found any answers yet. There is no practical requirement as such. I just wanted to see if there is some part of the C standard that I don't know of which will allow this. Thanks for any answers
Yes, but only if it is declared as static inline.
Functions that are declared simply as inline behave exactly like functions that are defined with no modifiers, except that they may be inlined within the translation unit that they're defined as inline in. They still have global scope, so including them in a header file will result in errors, as the function will be multiply defined.
static inline functions, on the other hand, do not have global scope — they only exist where they are used, more in line (ha ha) with the way you probably think of inline functions. As such, they're appropriate for use in header files.
No C function should not be defined in Header files.
function declaration can go in Header files.
But function definition should not ever go in header files.
Reason:
If function defination goes in header files then header will be included by multifple c files and when they are going to compile they will give error for multi defination of same files.
static inline function can be defined in Header files.
But that should not be used because
The "static" keyword in "static inline" is harmful in the situation
where a "static inline" function gets included and compiled in N
different files and does not get inlined. In this situation, one would
typically want the N copies of this function to get merged into one,
to avoid code bloat. But the "static" keyword prevents that, forcing
the linker to not merge these redundant functions.
As a side note to the answers/discussion on inline functions, I believe that theoretically one could define a function in a header in the same way as in a normal .c file, providing the header was only included once and in single location.
Though I'm not sure if the standard explicitly forbids this or not, it follows from the idea that the contents of a header file are essentially being copied and pasted into the top of the source file in which it is included from which point of view, there would be no issue.
If a function declaration isn't in a header file (.h), but is instead only in a source file (.c), why would you need to use the static keyword? Surely, if you only declare it in a .c file, it isn't seen by other files, as you're not supposed to #include .c files, right?
I have already read quite a few questions and answers about this (eg. here and here), but can't quite get my head around it.
What static does is make it impossible to declare and call a function in other modules, whether through a header file or not.
Recall that header file inclusion in C is just textual substitution:
// bar.c
#include "header.h"
int bar()
{
return foo() + foo();
}
// header.h
int foo(void);
gets preprocessed to become
int foo(void);
int bar()
{
return foo() + foo();
}
In fact, you can do away with header.h and just write bar.c this way in the first place. Similarly, the definition for foo does not need to include the header in either case; including it just adds a check that the definition and declaration for foo are consistent.
But if you were to change the implementation of foo to
static int foo()
{
// whatever
return 42;
}
then the declaration of foo would cease to work, in modules and in header files (since header files just get substituted into modules). Or actually, the declaration still "works", but it stops referring to your foo function and the linker will complain about that when you try to call foo.
The main reason to use static is to prevent linker clashes: even if foo and bar were in the same module and nothing outside the module called foo, if it weren't static, it would still clash with any other non-static function called foo. The second reason is optimization: when a function is static, the compiler knows exactly which parts of the program call it and with what arguments, so it can perform constant-folding, dead code elimination and/or inlining.
The static keyword reduces the visibility of a function to the file scope. That means that you can't locally declare the function in other units and use it since the linker does not add it to the global symbol table. This also means that you can use the name in other units too (you may have a static void testOutput(); in every file, that is not possible if the static is omitted.)
As a rule of thumb you should keep the visibility of symbols as limited es possible. So if you do not need the routine outside (and it is not part of some interface) then keep it static.
It allows you to have functions with identical names in different source files, since the compiler adds an implicit prefix to the name of every static function (based on the name of the file in which the function is located), thus preventing multiple-definition linkage errors.
It helps whoever maintains the code to know that the function is not exposed as part of the interface, and is used only internally within the file (a non-static function can be used in other source files even if it's not declared in any header file, using the extern keyword).
In my program, I have a file called constants.h that declares the following matrix in a global scope (the matrix should be fully constant - if anyone sees a potential problem, let me know):
static unsigned char const MY_MATRIX[66][9] = {...};
In another file, let's call it main.c, I can actually reference this constant:
doSomething(var1, count, MY_MATRIX[42], TRUE, FALSE, thing);
But then I just read the definition of the keyword static and it's supposed to mean that the variable cannot be accessed outside the file it's defined in. (In this case, the desired behavior is that it should be accessed, but then it seems the extern keyword is the one to use!)
So, can anyone tell me why this works? Why is the variable not invisible? Thanks!
This is because you are declaring a static variable in a header: when you include the header in a C file, you get a brand-new definition independent of the other definitions. If you include the header in two files, you get two independent copies; if you include it in three C files, you get three independent copies, and so on. The copies do not conflict with each other, because the static definition hides them from the linker.
A proper way to make use of a shared piece of data allocated in a static memory is to make the declaration extern in the header, and then add a non-static definition in exactly one C file.
If it's in a header, it's defined in every single source file you include it in (though each source file will have their own instantiation of it - they don't access the same one).
There are two uses of the static keyword:
A static variable inside a function block keeps its value between subsequent calls.
A static global variable or a function is "visible" only in the file it has been declared in.
Here, you define the matrix in a header file, hence it is visible to all the .c files which include that header file. To restrict its visibility, define it in a .c file instead.
Usually when a static variable is declared in a header file its scope is not limited to .h file meaning nothing like header file scope. The translation unit includes the text from header file in source file. Therefore every translation unit including header file gets its own individual variable though it is static scope.
Are function declarations/prototypes necessary in C99 ?
I am currently defining my functions in a header file and #include-ING it in the main file. Is this OK in C99 ?
Why do most programmers declare/prototype the function before main() and define it after main() ? Isn't it just easier to define them before main and avoid all the declarations/prototypes ?
Contents of header.h file:
int foo(int foo)
{
// code
return 1;
}
Contents of main file:
#include <stdio.h>
#include "header.h"
int main(void)
{
foo(1);
return 0;
}
How and where to prototype and define a function in C :
Your function is used only in a specific .c file :
Define it static in the .c file. The function will only be visible and compiled for this file.
Your function is used in multiple .c files :
Choose an appropriate c file to host your definition (All foo related functions in a foo.c file for example), and have a related header file to have all non-static (think public) functions prototyped. The function will be compiled only once, but visible to any file that includes the header files. Everything will be put together at link time. Possible improvement : always make the related header file, the first one included in its c file, this way, you will be sure that any file can include it safely without the need of other includes to make it work, reference : Large Scale C++ projects (Most of the rules apply to C too).
Your function is inlinable (are you sure it is ?) :
Define the function static inline in an appropriate header file. The compiler should replace any call to your function by the definition if it is possible (think macro-like).
The notion of before-after another function (your main function) in c is only a matter of style. Either you do :
static int foo(int foo)
{
// code
return 1;
}
int main(void)
{
foo(1);
return 0;
}
Or
static int foo(int foo);
int main(void)
{
foo(1);
return 0;
}
static int foo(int foo)
{
// code
return 1;
}
will result in the same program. The second way is prefered by programmers because you don`t have to reorganize or declare new prototypes every time you declare a new function that use the other ones. Plus you get a nice list of every functions declared in your file. It makes life easier in the long run for you and your team.
People typically do it because it's easier to do with multiple files. If you declare in a header then you can just #include that header anywhere you need those functions. If you define them in a header and then include in another translation unit, bang.
Function declarations are required in C99. Function prototypes are not required in C99.
Declaring functions before the point of the call and defining them after the point of the call is a popular approach to structuring the program code. However, this is in no way what the "most" programmers do. On the contrary, a more popular approach is to define function before the point of the first call, in which case the separate declaration is not necessary. This approach requires less maintenance, which is why it is more popular than what you describe.
Separate declarations/definitions are normally used with external functions only, i.e. with functions used across several translation units. Such functions are declared in header files and defined in implementation files.
You should only ever define inline functions in headers. Although you can have extern inline functions, the common case is static inline.
Rule of thumb for header files:
function declarations should be extern
function definitions should be static inline
variable declarations should be extern
variable definitions should be static const
As C. Ross asked for it, here's reasoning behind it: A resource with external linkage should only ever be defined once[1]. It follows that definitions should not reside in header files, which are intended to be included in more than one place.
Having static definitions in header files won't lead to any problems, but is generally frowned upon because the code has to be compiled more than once and will be present in different object files, which will increase the executable size (assuming the linker isn't smart enough to figure out the code duplication).
The common exceptions to this rule are constants and inline functions, which are supposed to be visible to the compiler in each translation unit to make further optimizations possible.
Note: [1] This does not apply to inline functions with external linkage, but as it's unspecified which of the multiple definitions of an inline function will be used in the evaluation of a function designator, they are mostly useless
Your approach is fine for small programs. Header files are meant for declarations and constant definitions - they provide an interface to the program they "encapsulate". Headers are meant as an interface for other program units.
In case you have more .c files, forward declarations and header files are necessary, because a C function can be defined only once for the whole program (search for one definition rule), even though you may use the function anywhere (in any .c file). If you defined it in a header, it would get included in all .c files you use it in and result in multiple definitions.
It's quicker to do like that, but I personally prefer to have the main function at the beginning of the main file, and put the other functions in other files or below main.
Note that in your example you should avoid declaring foo() in a header file: you won't be able to include it in two different source files. Declare it in the C file containing main(); you won't need to define it elsewhere unless you're referring to it from some other files.
Yes, it is easier to define them before main. If you only want to use these functions from within the file, a prototype is not necessary. In that case however, you can also prepend the "static" keyword before the function definition. (In the C file.) That will ensure the function is not visible to other files. (At link time.)
Do not put static keywords in include files.
You should always prototype.
The reasons for this are;
methodical prototyping produces a succinct list in header files of the functions in the code - this is invaluable to future readers
in anything but the simplest projects, many functions will not have visibility prior to main.
main should be the first function in its file; it's easier for the reader, since we read down, not up
Why do most programmers declare/prototype the function before main() and define it after main() ?
Merely because most humans read sequentially. Start a story from the beginning, not the middle. Not necessary, just intuitive.
Of course if the code being prototyped is in a separate compilation unit, the prototypes are necessary.
It is always a good practice to declare the functions in either before main or in a separate header file which will be included in other c files where we have used that function. By doing this we can easily identify all the functions declared/defined in that .C or .H files. And we should use extern key word before declaring the function in header file.