Is it possible to block access to variables and functions as you would by having a separate file but in the same file? Like how in javascript you would use anonymous functions.
You can have hiding in the sense that the declaration of the static function or static variable can follow after the function it is hiding from. Using a macro, you can hack your way into hiding a function or variable after it has been defined.
static void foo () { /* ... */ }
static int g_hidden_from_foo;
static void bar () { /* can use foo() */ }
#define foo foo_is_now_private
/* effectively hides foo */
This may satisfy your curiosity, but I can't say it is convenient (or wise).
If you are open to using compiler extensions, GCC has nested functions, which is more or less similar to anonymous functions.
This is not directly possible in C. The unit of code in C is the translation unit, which is the fancy way of saying the file you're editing (plus header files).
Any code in a particular translation unit can "see" any of the preceding declarations and definitions. There is no way to change that in standard C. You can use macros or naming tricks to hide identifiers, but you can't outright stop access, especially not in a readable/convenient way.
If you're willing to use separate files you can simply avoid putting a declaration in your public header file to make the data "hidden" and can make function declarations as static to make them completely inaccessible to other translation units.
If you use C++ instead then you can get a bit further by using classes with protected and private members, as C++ protection semantics are per-class rather than per-translation-unit.
Related
I have heard that, when you have just 1 (main.c) file (or use a "unity build"), there are benefits to be had if you make all your functions static.
I am kind of confused why this (allegedly) isn't optimized by default, since it's not probable that you will include main.c into another file where you will use one of its functions.
I would like to know the benefits and dangers of doing this before implementing it.
Example:
main.c
static int my_func(void){ /*stuff*/ }
int main(void) {
my_func();
return 0;
}
You have various chunks of wisdom in the comments, assembled here into a Community Wiki answer.
Jonathan Leffler noted:
The primary benefit of static functions is that the compiler can (and will) aggressively inline them when it knows there is no other code that can call the function. I've had error messages from four levels of inlined function calls (three qualifying “inlined from” lines) on occasion. It's staggering what a compiler will do!
and:
FWIW: my rule of thumb is that every function should be static until it is known that it will be called from code in another file. When it is known that it will be used elsewhere, it should be declared in a header file that is included both where the function is defined and where it is used. (Similar rules apply to file scope variables — aka 'global variables'; they should be static until there's a proven need for them elsewhere, and then they should be declared in a header too.)
The main() function is always called from the startup code, so it is never static. Any function defined in the same file as an unconditionally compiled main() function cannot be reused by other programs. (Library code might contain a conditionally compiled test program for the library function(s) defined in the source file — most of my library code has #ifdef TEST / …test program… / #endif at the end.)
Eirc Postpischil generalized on that:
General rule: Anytime you can write code that says the use of something is limited, do it. Value will not be modified? Make it const. Name only needs to be used in a certain section? Declare it in the innermost enclosing scope. Name does not need to be linked externally? Make it static. Every limitation both shrinks the window for a bug to be created and may remove complications that interfere with optimization.
In our project, we have pretty big C file of around 50K lines, written in 90's.
I wanted to split the file based on the functionality. But, all the functions in this file are declared as static. So, file scoped. If I split the file, then the function in file1 cannot call function in file2 and vice-versa.
But, My TL feels like that there could be memory optimization by using static functions.
I wrote some sample code to see if the stacks are different for different threads.
It seemed like it was. Could someone please enlighten me the difference between static function and a normal one other an file scope?
In C, while defining a function, the static keyword has the following 2 major consequences :
Prevents the function name from being exported (i.e. function does NOT have external linkage). Thus, preventing linkage / direct calls from other parts of the code.
As the function is clearly marked private to the file, the compiler is in a better position to generate a complete call-graph for the function. This may result in the compiler deciding to automatically in-line the function for better performance.
All functions are implicitly declared as extern, which means they're visible across translation units. But when we use static it restricts visibility of the function to the translation unit in which it's defined. So we can say Functions that are visible only to other functions in the same file are known as static functions.
The most important difference is you cannot call the static function in any other files. i think so ,yeah?
IMO both make the function to have a scope of the translation unit only.
What's the difference between "static" and "static inline" function?
Why should inline be put in a header file, not in .c file?
By default, an inline definition is only valid in the current translation unit.
If the storage class is extern, the identifier has external linkage and the inline definition also provides the external definition.
If the storage class is static, the identifier has internal linkage and the inline definition is invisible in other translation units.
If the storage class is unspecified, the inline definition is only visible in the current translation unit, but the identifier still has external linkage and an external definition must be provided in a different translation unit. The compiler is free to use either the inline or the external definition if the function is called within the current translation unit.
As the compiler is free to inline (and to not inline) any function whose definition is visible in the current translation unit (and, thanks to link-time optimizations, even in different translation units, though the C standard doesn't really account for that), for most practical purposes, there's no difference between static and static inline function definitions.
The inline specifier (like the register storage class) is only a compiler hint, and the compiler is free to completely ignore it. Standards-compliant non-optimizing compilers only have to honor their side-effects, and optimizing compilers will do these optimizations with or without explicit hints.
inline and register are not useless, though, as they instruct the compiler to throw errors when the programmer writes code that would make the optimizations impossible: An external inline definition can't reference identifiers with internal linkage (as these would be unavailable in a different translation unit) or define modifiable local variables with static storage duration (as these wouldn't share state accross translation units), and you can't take addresses of register-qualified variables.
Personally, I use the convention to mark static function definitions within headers also inline, as the main reason for putting function definitions in header files is to make them inlinable.
In general, I only use static inline function and static const object definitions in addition to extern declarations within headers.
I've never written an inline function with a storage class different from static.
inline instructs the compiler to attempt to embed the function content into the calling code instead of executing an actual call.
For small functions that are called frequently that can make a big performance difference.
However, this is only a "hint", and the compiler may ignore it, and most compilers will try to "inline" even when the keyword is not used, as part of the optimizations, where its possible.
for example:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
This tight loop will perform a function call on each iteration, and the function content is actually significantly less than the code the compiler needs to put to perform the call. inline will essentially instruct the compiler to convert the code above into an equivalent of:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Skipping the actual function call and return
Obviously this is an example to show the point, not a real piece of code.
static refers to the scope. In C it means that the function/variable can only be used within the same translation unit.
From my experience with GCC I know that static and static inline differs in a way how compiler issue warnings about unused functions. More precisely when you declare static function and it isn't used in current translation unit then compiler produce warning about unused function, but you can inhibit that warning with changing it to static inline.
Thus I tend to think that static should be used in translation units and benefit from extra check compiler does to find unused functions. And static inline should be used in header files to provide functions that can be in-lined (due to absence of external linkage) without issuing warnings.
Unfortunately I cannot find any evidence for that logic. Even from GCC documentation I wasn't able to conclude that inline inhibits unused function warnings. I'd appreciate if someone will share links to description of that.
One difference that's not at the language level but the popular implementation level: certain versions of gcc will remove unreferenced static inline functions from output by default, but will keep plain static functions even if unreferenced. I'm not sure which versions this applies to, but from a practical standpoint it means it may be a good idea to always use inline for static functions in headers.
In C, static means the function or variable you define can be only used in this file(i.e. the compile unit)
So, static inline means the inline function which can be used in this file only.
EDIT:
The compile unit should be The Translation Unit
In C++, one important effect of inline (that is not mentioned in the other answers yet, I think) is that it prevents linker errors when multiple definitions of the function are found.
Consider a function that is defined in a header file to allow it to be inlined into the source files that include the header. If the compiler decides to not inline (all calls to) this function, the function definition will be included into every object file that references it (i.e. does not inline all calls).
This might cause multiple definitions of the functions to read the linker (though not always, since it depends on the inlining decisions made by the compiler). Without the inline keyword, this produces a linker error, but the inline keyword tells the linker to just pick one definition and discard the rest (which are expected to be equal, but this is not checked).
The static keyword, on the other hand, ensures that if a function is included in the object file, it will be private to that object file. If multiple object files contain the same function, they will coexist and all calls to the function will use their "own" version. This means that more memory is taken up. In practice, I believe this means that using static for functions defined in header files is not a good idea, better to just use inline.
In practice, this also means that static functions cannot produce linker errors, so the effect of inline above is not really useful for static functions. However, as suggested by ony in another answer, adding inline might be helpful to prevent warnings for unused functions.
Note that the above is true for C++. In C, inline works a bit different, and you have to explicitly put an extern declaration in a single source file to have the inline function emitted into that object file so it is available for any non-inlined uses. In other words, inline means that a function is not emitted into any source file, even when not all calls are inlined, unless it is also specified as extern, and then it is emitted (even if all local calls are inlined). I'm not sure how that interacts with static, though.
An inline definition is not externally linked.
// average.h
#ifndef AVERAGE_H
#define AVERAGE_H
inline double average(double a, double b);
#endif
Attempting to call an inline function with the definition above from another
module after it has been preprocessed or linked to a c file will result in an error.
There are two ways to solve this problem:
make it a static inline function defintion.
Example:
// average.h
#ifndef AVERAGE_H
#define AVERAGE_H
static inline double average(double a, double b);
#endif
include the defintion from the c file and make it external.
Example:
#include "average.h"
extern double average(double a ,double b){
return (a + b) / 2;
}
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.
I wonder about the use of the static keyword as scope limiting for variables in a file, in C.
The standard way to build a C program as I see it is to:
have a bunch of c files defining functions and variables, possibly scope limited with static.
have a bunch of h files declaring the functions and possibly variables of the corresponding c file, for other c files to use. Private functions and variables are not published in the h file.
every c file is compiled separately to an o file.
all o files are linked together to an application file.
I see two reasons for declaring a gobal as static, if the variable is not published in the h file anyway:
one is for readability. Inform future readers including myself that a variable is not accessed in any other file.
the second is to prevent another c file from redeclaring the variable as extern. I suppose that the linker would dislike a variable being both extern and static. (I dislike the idea of a file redeclaring a variable owned by someone else as extern, is it ok practice?)
Any other reason?
Same goes for static functions. If the prototype is not published in the h file, other files may not use the function anyway, so why define it static at all?
I can see the same two reasons, but no more.
When you talk about informing other readers, consider the compiler itself as a reader. If a variable is declared static, that can affect the degree to which optimizations kick in.
Redefining a static variable as extern is impossible, but the compiler will (as usual) give you enough rope to hang yourself.
If I write static int foo; in one file and int foo; in another, they are considered different variables, despite having the same name and type - the compiler will not complain but you will probably get very confused later trying to read and/or debug the code. (If I write extern int foo; in the second case, that will fail to link unless I declare a non-static int foo; somewhere else.)
Global variables rarely appear in header files, but when they do they should be declared extern. If not, depending on your compiler, you risk that every source file which includes that header will declare its own copy of the variable: at best this will cause a link failure (multiply-defined symbol) and at worst several confusing cases of overshadowing.
By declaring a variable static on file level (static within function has a different meaning) you forbid other units to access it, e.g. if you try to the variable use inside another unit (declared with extern), linker won't find this symbol.
When you declare a static function the call to the function is a "near call" and in theory it performs better than a "far call". You can google for more information. This is what I found with a simple google search.
If a global variable is declared static, the compiler can sometimes make better optimizations than if it were not. Because the compiler knows that the variable cannot be accessed from other source files, it can make better deductions about what your code is doing (such as "this function does not modify this variable"), which can sometimes cause it to generate faster code. Very few compilers/linkers can make these sorts of optimizations across different translation units.
If you declare a variable foo in file a.c without making it static, and a variable foo in file b.c without making it static, both are automatically extern which means the linker may complain if you initialise both, and assign the same memory location if it doesn't complain. Expect fun debugging your code.
If you write a function foo () in file a.c without making it static, and a function foo () in file b.c without making it static, the linker may complain, but if it doesn't, all calls to foo () will call the same function. Expect fun debugging your code.
My favorite usage of static is being able to store methods that I wont have to Inject or create an object to use, the way I see it is, Private Static Methods are always useful, where public static you have to put some more time in thinking of what it is your doing to avoid what crazyscot defined as, getting your self too much rope and accidentally hanging ones self!
I like to keep a folder for Helper classes for most of my projects that mainly consist of static methods to do things quickly and efficiently on the fly, no objects needed!