Making a function only accessible from one other function - c

How can I declare and define a function so that it is only accessible from a single function? I can declare a function in another function. But since local function definitions are illegal (according to Visual C++) I must define the function at global scope, making it possible for other functions to call it.
void f1() {
void f1_private();
f1priv();
}
void f1_private() {
}
void f2() {
f1_private(); // Legal
}
Is it possible to make f1_private only accessible from f1? If not, what are the uses for locally declared functions?

You can put both functions into a single separate file and make the one you want to be less visible static. A static function in C is only accessible from the same source file in which it was declares (sort of a poor-man's namespace concept).
You then just expose the visible function in your header files as you'd normally do.

The best you can do is to put the two functions in their own file, and declare the "private" one to have static linkage (by prefixing the declaration with the word 'static'). Functions with static linkage are accessible only withing their compilation unit (usually meaning the same file, in most build systems).
If the non-private function has to be called from elsewhere, you would then have to either write its prototype in each file it is called from, or create a header file containing the prototype which is included in each file it is called from.

No.
But you can write in C++, declare method inside class, make method private, and make another class friend of first class.

Put a comment on it.
//For use only by foo.
If someone is really gung-ho about using it, they will find a way despite your best efforts. Even if it means just copying and pasting the code, or refactoring the code. The best thing to do is let them know they shouldn't.
You can also encapsulate it by making it private, if it's in a class. Or static if it isn't.

// at the bottom of your .c file
static void foo()
{
}
void dude()
{
// foo only accessible here, unless you have forward
// declared it higher up in the file
foo();
}
However, note that even static methods can be called outside file scope through a function pointer.

You can declare a separate class, with a public member for one function, and a private member function for the one you want only accessible from the other. If this is only used within a class you can make it an internal class.

Related

Resolving function name conflicts by using static

Say we have a library that defines the following internally used function skip_comments, that is used only by the translation unit it is defined in
void skip_comments(...)
{
}
void another_function()
{
skip_comments(...) //calls the above function --- (1)
}
Now this library is used by another process which also has a function with the same name skip_comments.
This will cause a function name conflict between the library function vs the function defined in the process. So at the point (1) I might expect it to call the process's function instead of the library function which clearly is a bug.
As a possible fix, I made the skip_comment function static and now the bug seems to be fixed. But I'm not sure if this is a proper fix
My question is, would defining the skip_comment as static ensure that at (1) such a name conflict will not occur? ie.
static void skip_comments(...)
{
}
void another_function()
{
skip_comments(...) // will it always call the internal function?
}
Or the only solution is to make sure we define a unique name for functions such as adding prefixes?
Declaring a function as static means that it will only be accessible by the translation unit where it is declared. (Translation unit meaning the .c file and all .h files included by that .c file.)
So yes, declaring it as static will solve your name conflicts. Given that you do this consistently everywhere and not just in one file.
However, it is good practice to prefix all identifiers based on the module where they belong, so that is perhaps the best solution regardless.

Functions that call each other, declared inside another function

I have two functions that call each other, inside of another function:
int main(){
void aaa();
void b(){
aaa();
}
void aaa(){
b();
}
aaa();
}
(Yes, this example would be stuck in an infinite loop or cause a stack overflow)
The compiler throws the error: static declaration of 'aaa' follows non-static declaration
If I move the function declarations outside of the other function, it works (but I can't do that because those functions need to have access to main's local variables)
Is it possible to make this work?
C does not support nested functions, nor closures.
One solution for your actual problem is to define the shared state (the local variables of main you mentioned, in this case) as struct, then have variable of this struct type, and pass it as pointer to the functions that use it.
You don't show the local variable code in your question, so I'm not writing and arbitrary example. Please edit the question with more code, if you want an example.
Another solution is to just use global (preferably static) variables, used both from other functions and main. I mean, since main isn't a normal function (can't be called recursively by standard, for example), its local variables end up being unique objects anyway, so this is just a matter of scope and visibility, with little to no funcional difference.

What happens if I don't declare all functions in header?

I'm currently practicing a unit test with GTest, and noticed that I didn't declare all functions written on the target source code (target.c) to its header (target.h). Since I didn't do the test for those undeclared functions, I couldn't notice until now.
Now, it seems that those header-undeclared functions work as 'private' functions since they are not callable from the test code (which includes header of the target source code).
Can I consider this as a way to declare a private function or should I be aware of something else for safety?
No. that does not make your function private. It just then requires the caller to extern that function themselves. Using the static key word is the appropriate way to create a private function. Eg:
static void myfunc ()
{
...
}
Not including it in the header doesn't make it a private function, since any other C file could add an extern void myfunc() in either their header or C code and gain access to that function. At compile time, all of that is going to be linked (assuming you are compiling all the files).
BUT all static objects will only have module level (or file scope) visibility
The same goes for variables you only want in the filescope.

Move an interrupt handler and variables from main to a include file

I've a newbie question about how to correctly move an interrupt handler to an include file. I've a SysTick handler in my main.c file defined in this way:
volatile int systick_timer_counter = 0;
void SysTick_Handler(void) {
systick_timer_counter++;
}
I use this systick_timer_counter, that is increased every 10 ms, to trigger some checks after some time has passed, then reset it.
What I want is to use this systick_timer_counter also inside some functions that aren't in my main.c file, but in another function's .c file. So I want to create a file called systick_counter to include where I need to use it.
What I'm asking is, how should I do this in correct way? I can just create a .c file and place variable and interrupt header inside it, or should I add something more or change variable definition?
It sounds like you mean you want to have a global variable defined in
one module (source file) that’s accessible from other modules.
Assuming I’ve interpreted your question correctly, yes, that can be done
by using the extern keyword. However, it would be irresponsible of me
not to say that using globals unnecessarily is bad practice. It
results in hard-to-maintain code, because an extern global might be
changed from anywhere in the code base. You want to limit scope and
visibility of your identifiers as much as you can.
In this instance, I would recommend that you instead keep
systick_timer_counter local to the module in which it’s defined, and
use functions in that module to access it. It’s like defining a class
with methods, in a language that doesn’t have explicit classes. Doing it
this way, other modules can’t change the value except by calling
reset_systick().
int systick_timer_counter = 0;
void reset_systick()
{
systick_timer_counter = 0;
}
void SysTick_Handler()
{
systick_timer_counter++;
}
int return_systick()
{
return systick_timer_counter;
}
It's also a good idea to add the static keyword to variables that you want to only be accessible from within the file.
static int systick_timer_counter = 0;

static and external variables

What are the differences between static and external variables? What are the advantages of making a static variable?
Why do we prefer making external variables in multifunction programs? The book says that else it gets initialized very late. I don't get it.
Problem is that in C static can have different meanings. I will try to give an overview of the different situations in the following paragraphs.
If a variable is defined outside a function, it can be used by all functions in the file. Sometimes also called 'global variable'. This means that there is only one instance of this variable for the whole file. Also the name of the variable is stored in the resulting .OBJ file. This latter is important, since if another file also defines a variable with the same name outside a function, the linker assumes that it's the same variable in both cases, and merges them.
To make this extra clear, it's best to add the keyword "extern" to one of the variables. In this case, we say that we declare the variable, instead of defining it. It is an extra signal for the compiler/linker to indicate that we actually want to refer to a global variable defined somewhere else.
If you want to define a global variable, but don't want to make it available to other files, add the keyword static before. The keyword static tells the compiler that the variable name must not be stored in the .OBJ file. This means that two .C files with the following line:
static long MyGlobalVariable;
will each have their own variable. Both variables will be called MyGlobalVariable.
If you define a variable inside a function, it becomes a local variable. It comes into existence if the function is called, and disappears again after the function is finished.
In some situations you want to keep the value of the variable in between function calls. You could do this by using a global variable (instead of a local variable) but then the variable becomes available for all functions in the file, which you don't necessarily want. In that case you can put the keyword static before the variable, like this:
void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}
The first time the function is called, MyLocalVariable will be 'created' and initialized with the value 0. At the end of the function, the variable is not destroyed, but kept. So the next time you call this function, the value of the variable will be 1, not zero.
In C it really doesn't matter whether you put the variable outside the function (as global variable) or define it as static inside the function. The only difference is where the variable can be accessed.
In C++, things are quite different. If you write this (outside a function):
MyClass MyGlobalVariable;
MyGlobalVariable will be constructed (this is: the constructor will be executed) at the start of the application, before even main is called. However, you don't have real control over the order in which all global variables are constructed.
So if another file contains this:
MyOtherClass MySecondGlobalVariable;
You can't know for sure whether MyGlobalVariable or MySecondGlobalVariable is constructed first. This can give problems if the constructor of one of them relies on the presence (construction) of the other one.
On the other hand, if you define the variable as static inside a function:
void MyFunction()
{
static MyClass MyStaticVariable;
}
Then MyStaticVariable will be constructed the first time the function is called. With this construction, you can write something like this:
MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}
And we have implemented a singleton where we have control on when it is constructed. The first time we need it, it's constructed.
To be honest, this approach is a rather simplistic one, because it may lead to problems in multi-threaded applications. In that case, there are other tricks.
"Static" more or less means "this will always exist". Depending on the context, you get different results:
static int global_variable;
void function()
{
static int global_function_variable;
}
class foo
{
static void function()
{
static int foo_function_variable;
//...
}
static int foo_variable;
}
global_variable - Only ever visible within the "translation unit". (Since headers are more or less copied in, does this mean a static global in a header exists as separate variables for all cpp files it's included in?)
global_function_variable is created the first time function is called, and will continue to exist throughout the program's lifetime. The value persists, so if you change it in one function call, the next function call will use the changed variable.
foo::function() is a function that can be called like a global function; you don't need to have an instance of foo to call it. This means it doesn't have a valid this pointer, however. Similarly, foo_variable exists even when there aren't any foo objects. All foo objects have the same foo_variable - if you change it in one object, all other objects "see" the change.
foo_function_variable behaves, I think, just like global_function_variable.
The basic idea behind extern is to control the linkage of a variable:
From MSDN :
// specifying_linkage1.cpp
int i = 1;
void other();
int main() {
// Reference to i, defined above:
extern int i;
}
void other() {
// Address of global i assigned to pointer variable:
static int *external_i = &i;
// i will be redefined; global i no longer visible:
// int i = 16;
}
extern int global_variable;
extern can also be used to link a variable using another language, most commonly, C.
global_variable is the most common usage of extern; it says that elsewhere, there's a variable called "global_variable", and we're going to be using that variable. Somewhere, you need to declare the variable without the extern keyword, or it is never actually created.

Resources