initializing a function externally - c

I would like to return a function with a variable inside it that I can initialize inside the function that returns it. Possible, or no?
int get_char (char *c)
{
static circular_queue *cir; // this needs to be initialized in the function below
if (circular_queue_empty(cir))
return 0;
else
*c = circular_queue_pop(cir);
return 1;
}
int (*generate_get_char(circular_queue *cir)) (char *c)
{
// do something to set cir
return &get_char;
}
I am passing the pointer to getchar into an API that I do not control so I cannot change the format of get_char; that being said, is there a better way of doing this as I am pretty sure the above is not possible. (I would rather not use a static global, but thats all I can think of doing).
TY

Variables which have static storage allocation are default initialized to zero. Therefore, the following statements are effectively equivalent.
static circular_queue *cir;
// equivalent to
static circular_queue *cir = 0;
// equivalent to
static circular_queue *cir = NULL;
The variable cir has function scope, i.e., it can be accessed only in the function get_char. Therefore, the answer to your question
I would like to return a function with a variable inside it that I can
initialize inside the function that returns it. Possible, or no?
is no. You need a global variable which is visible to both the functions get_char and generate_get_char. Also, note that a function name implicitly converts to a pointer. Therefore, the following are equivalent -
return &get_char;
// equivalent to
return get_char;

This is not possible - cir is accessible only from get_char and there is no way to access it from outside. You need a static global visible by both functions.

Related

how to return a pointer value from function to array of strings in c? [duplicate]

Is the following code (func1()) correct if it has to return i? I remember reading somewhere that there is a problem when returning a reference to a local variable. How is it different from func2()?
int& func1()
{
int i;
i = 1;
return i;
}
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
This code snippet:
int& func1()
{
int i;
i = 1;
return i;
}
will not work because you're returning an alias (a reference) to an object with a lifetime limited to the scope of the function call. That means once func1() returns, int i dies, making the reference returned from the function worthless because it now refers to an object that doesn't exist.
int main()
{
int& p = func1();
/* p is garbage */
}
The second version does work because the variable is allocated on the free store, which is not bound to the lifetime of the function call. However, you are responsible for deleteing the allocated int.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Typically you would wrap the pointer in some RAII class and/or a factory function so you don't have to delete it yourself.
In either case, you can just return the value itself (although I realize the example you provided was probably contrived):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Note that it's perfectly fine to return big objects the same way func3() returns primitive values because just about every compiler nowadays implements some form of return value optimization:
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
Interestingly, binding a temporary to a const reference is perfectly legal C++.
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
A local variable is memory on the stack, and that memory is not automatically invalidated when you go out of scope. From a function deeper nested (higher on the stack in memory), it’s perfectly safe to access this memory.
Once the function returns and ends though, things get dangerous.
Usually the memory is not deleted or overwritten when you return, meaning the memory at that address is still containing your data - the pointer seems valid.
Until another function builds up the stack and overwrites it.
This is why this can work for a while - and then suddenly cease to function after one particularly deeply nested set of functions, or a function with really huge sized or many local objects, reaches that stack-memory again.
It even can happen that you reach the same program part again, and overwrite your old local function variable with the new function variable. All this is very dangerous and should be heavily discouraged.
Do not use pointers to local objects!
A good thing to remember are these simple rules, and they apply to both parameters and return types...
Value - makes a copy of the item in question.
Pointer - refers to the address of the item in question.
Reference - is literally the item in question.
There is a time and place for each, so make sure you get to know them. Local variables, as you've shown here, are just that, limited to the time they are locally alive in the function scope. In your example having a return type of int* and returning &i would have been equally incorrect. You would be better off in that case doing this...
void func1(int& oValue)
{
oValue = 1;
}
Doing so would directly change the value of your passed in parameter. Whereas this code...
void func1(int oValue)
{
oValue = 1;
}
would not. It would just change the value of oValue local to the function call. The reason for this is because you'd actually be changing just a "local" copy of oValue, and not oValue itself.

what is the effect of *pe=pn->Entry;?

All I need to understand is what is that line mean:
*pe=pn->Entry;
Why can't I skip it.how does it affect the serve operation?
void Serve(Entrytype *pe,Queue *pq){
QueueNode *pn;
*pe=pn->Entry;
pn=pq->front;
pq->front=pn->next;
free(pn);
}
It doesn't affect the function itself, however it essentially acts as a return value, setting a value outside the function denoted by the pointer for later use. So, if you omit the line, the function will still work, but what comes after the function might not.
This is a common C technique to allow for mutable arguments. A typical case looks like this:
void mutate(int* a) {
*a = 5;
}
Where when called:
int main() {
int a = 0;
mutate(&a);
printf("a=%d\n", a);
return 0;
}
Will now show that a has been altered.
If this were a non-pointer argument, like this:
void mutate(int a) {
a = 5;
}
Then you're only changing the local variable a and it has no effect on the caller's variable.

Accessing variables in another function without the variable being in the function parameter

void foo() {
int i = 3;
bar();
}
void bar() {
//print i in foo()
}
I was wondering if there is some way that I could do this without setting a global variable?
No, this is a local variable and is stored in the stack for that method, outside that method the stack does not exist and can not be read
If you want to just use the value of i, you can use:
void bar(int i);
void foo() {
int i = 3;
bar(i);
}
void bar(int i) {
//print i in foo()
}
If you want to be able modify the value of i, use:
void bar(int* ip);
void foo() {
int i = 3;
bar(&i);
}
void bar(int* ip) {
*ip = 20;
}
C uses static scoping. You can check this here: https://msujaws.wordpress.com/2011/05/03/static-vs-dynamic-scoping/ :)
Simply pass i from foo to bar as parameter:
bar(i);
void bar(int i)
You can, but you have to pass it to foo as an argument. The reason for this is that when a C function is called it creates any local variables defined inside it on the stack, which is essentially just a form of dynamic memory allocation. When the function returns, it frees the memory used by those variable. Now you might think there should be some way for bar to know about i since it is still present on the stack when bar is called inside foo. But the problem is that C does not make any assumptions about who might be calling the bar function. You could just as easily call bar from a third function that has no i defined within it. For this reason there is no mechanism for accessing stack variables from a nested function without passing them explicitly.
Interestingly, having the ability to do this built into the language is one of the key features that allows for the implementation of closures. So if you have ever struggled to understand what made these so special, this is basically it. Probably not as spectacular as the hype might have lead you to believe.

What does it mean to declare variables as static in a function?

I was looking for a function to do some audio effect, and I found one written in C.
Inside this function, some variables are declared as Static. I am confused, I thought Static means these variables are not visibles to other files. But since they are declared inside inside a function, they are already not visible to other files.
What am I missing ?
static inside a function means that it will hold its value the next time the function is called.
For example,
int foo() {
static int i = 0;
printf("%d\n", i);
i++;
}
int main() {
foo(); // Prints 0
foo(); // Prints 1
}

Effect of return type being static

What are the possible effect of returning a static type data. And when should we actually use it?
static ssize_t
my_read(int fd, char *ptr)
{
//code from Stevens Unix Network programming.
if (something)
return (-1)
if (something else)
return (0)
return (1)
}
why static here?
Thanks.
The function is static, not the return type. This means that its name is only visible from within the current compilation unit, which is used as an encapsulation mechanism.
The function can still be called from elsewhere through a function pointer, however.
See also this discussion on the general static keyword for more context.
We use static data type when returning a pointer to a variable created in called function.for e.g
float * calculate_area(float r)
{
float *p;
static float area;
p=&area;
area=3.14*r*r;
return p;
}
If you would make area as automatic variable i.e without any type qualifier it would be destroyed when control returns from called function.When declared as static you could correctly retrieved the value of area from main also.Thus it in order for it to persists its value we make it as static.
By using static , Access to static functions is restricted to the file where they are declared
Another reason for making functions static is to reuse the same function name in other files.
//file1
static void fun1(void)
{
cout<<"file1";
}
// file2
// now if we include file1 and use fun1 in file2 , it
// will show “undefined reference to `fun1’” error as
// it fun1 is defined static
int main(void)
{
fun1();
getchar();
return 0;
}

Resources