What is the issue with this C function that contains a function? - c

My professor showed us this code:
timerX(int x){
int times(int y){
return x * y;
}
return times;
}
How does this work in C(using GCC compiler)? He said that as soon as the function disappears the inside function disappears? I appreciate any tips or advice.

It's called a nested function, a GNU extension. Basically
the inner function can acess the local variables of the outer function (the ones declared prior to its apparition)
the inner function can only be called from outside via function poinyers but not after the containing function has terminated if the inner function accesses objects from its parent
In your example, calling that function pointer from outside will probably be illegal.
If you try to call the nested function through its address after the
containing function has exited, all hell will break loose.

I'm pretty sure it works just like any other function, except that it is only visible to the enclosing function.
In other words, it's just related to the visibility or accessibility of the function, and nothing else.

Related

how to find recursive function name list in a c++ project

I want to find out all recursive functions's name in a c++ project which have many files.
Is there any IDE or scripts can do this?
It is not as easy as others may think.
A function call can be inside a double-quoted string or a comment, so you may want to remove these. When removing strings (or maybe replacing them by the word 0STRING), you should search for matching double quote. Be aware of \\ and \" tokens.
Even after you removed all these, finding function start, end, and call can be a challenge. Take into account template functions, for example. Also, f(a b){g(b);} is not neccessarily a function, if there is a macro f. Maybe you want to take this to account too.
Also:
The following function is recursive
class A {
F(int x) {
// ...
A::F(y);
}
}
while the following is not
class A {
F(int x) {
// ...
B::F(y);
}
}
Same about namespaces. Namespace qualifier, like class qualifier, may or may not make the function non-recursive.
You may want to create the cross reference links table with crange, and then process it with awk.
I'm afraid that you'd have to write your own script for this, and it's not quite trivial. You need to recognize the start and end of a function as well as a function call. That part isn't awful. However, you need to maintain a stack of nested functions, so you always know the innermost function at this parsing point. Whenever you find a call to the innermost function, you report that you've found recursion.
The minorly tricky case is something like this:
int func_a() {
...
int func_b() {
...
result = func_a()
}
recur = func_a()
The first call is not recursive; the second one is. The nesting can get deeper -- you have to count braces outside of literal strings -- add 1 for a left brace, subtract one for a right brace, and check the total for the "brace-nesting" number of the innermost function on your stack.
Does that help move you toward a solution?

Scope rules in C: Nested blocks

I have the following nested function:
int main()
{
int a, b, c;
a = 10;
int foo()
{
int a, b, c;
//some more code here
}
// some more code here
}
Now, I need to assign the variable a that belongs to foo(), with the value of the variable a that belongs to main(). Basically, something like foo.a = main.a is what I'm looking for.
Is there any way of doing this kind of assignment? I read through scope rules here and here , but didn't find anything I could use in this situation.
I know that using a nested function is not advisable, but I'm working on preexisting code, and I don't have permission to change the structure of the code.
How do I proceed?
Keeping apart the nested function part, AFAIK, C does not provied any direct way to access the shadowed variable.
Primary Advice: Do not use this approach. Always use separate variable names for inner scopes and supply -Wshadow to gcc to detect and avoid possible shdowing.
However, just in case, you have to use the same variable names for inner and outer scope and you have to access the outer scope variable from the inner scope, your best bet is to (in this very order, inside the inner block)
declare a pointer, assign the address of the outer variable to it.
declare and define the local variable.
use both.
Note: As a general word of advice, please try not to write new code (I understand the maintainance part) in this manner. It is both hard to manage and hard to read.

Is this a global?

I'm trying to understand this function and convert it to ctypes:
15 XDisplay* GetXDisplay() {
16 static XDisplay* display = NULL;
17 if (!display)
18 display = OpenNewXDisplay();
19 return display;
20 }
We see here if(!display) then do display = OpenNewXDisplay(); but what confuses me is the guy defines on the line above it that display is NULL (static XDisplay* display = NULL;) so why on earth the need for the if, if he just set it to null? Is display a global variable somehow?
display is a static variable.
For a static variable, initialisation only happens once, not every time the function is entered. This is just basic C (also basic C++, or basic Objective-C).
So this code is just a primitive way to create a singleton object.
As the others mentioned before display is a static variable.
The static storage class instructs the compiler to keep a local
variable in existence during the life-time of the program instead of
creating and destroying it each time it comes into and goes out of
scope. Therefore, making local variables static allows them to
maintain their values between function calls.
Source: http://www.tutorialspoint.com/cprogramming/c_storage_classes.htm
You should read more about whats static word means:
http://en.wikipedia.org/wiki/Static_variable
basicly it means that the variable will be defined only once. which means that on the next time the function will be called the previous value of the variable will be stay.
So its not quite a global variable since its has the scope of a regular variable but keeps its value over function calls.

Multiple instances of a variable (static, non-static)

I came across this piece of C code:
main(){
static int i=0;
i++;
if(i<=5){
int i = 3;
printf(" %d",i);
main();
}
}
1. First, I expected this code to give a compilation error as there are multiple definitions of the variable i. But, it compiled and ran successfully and gave this output.
3 3 3 3 3
2. Observing the output, 3 is printed exactly 5 times, which means the loop was counted from 0 to 5 thus implying that for the if condition , the first definition (static) of i was used.
3 However, the value being printed is 3 which is the 2nd definition of i.
So the variable label i is referring to two different instances in memory. One is being used as the loop count, to do the increment, and the other is the value being printed.
The only way I can somehow explain this is:
int i = 3 (the 2nd definition) is repeated in every recursive call. That instance of i is created when the function is called, and killed when the next recursive call is made. (Because of static scoping). printf uses this instance, as it is the latest definition(?)
When entering a new level of recursion, i++ is being done. Since there is no other way to resolve this i, it uses the static "instance" of i , which is still "alive" in the code as it was defined as static.
However, I'm unable to exactly put a finger on how this works..can anyone explain what's going on here, in the code and the memory?
How is the variable binding being done by the compiler here?
The inner scope wins.
Example:
int i = 1;
void foo() {
int i = 2; // hides the global i
{
int i = 3; // hides local i
}
}
This behavior is by design. What you can do is use different naming conventions for variable scopes:
global/statics
function arguments
locals
class/struct members
Some compilers will issue a warning if you hide a variable in the same function (e.g. function argument and regular local variable). So you the max warning level on your compiler.
The compiler will always use the most local version of a variable when more than one variable of that name exists.
Outside the loop, the first i is the only one that exists, so it is the one that is checked. Then a new i is created, with value 3. At this point whenever you talk about i it will assume you mean the second one, since that's more local. When you exit the loop, the second i will go out of scope and be deleted and so if you start talking about i again it will be the first one.
The {} of the if statement creates a new block scope and when you declare i in that scope you are hiding the i in the outer scope. The new scope does not start until { and thus the if statement is referring to the i in the outer scope.
Hiding is covered in the draft C99 standard section 6.2.1 Scopes of identifiers paragraph 4 says (emphasis mine):
[...]If an identifier designates two different entities in the same name
space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a
strict subset of the scope of the other entity (the outer scope). Within the inner scope, the
identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.

Using C variable inside Lua alongside nested functions

This is a sort of followup to my previous question about nested registered C functions found here:
Trying to call a function in Lua with nested tables
The previous question gave me the answer to adding a nested function like this:
dog.beagle.fetch()
I also would like to have variables at that level like:
dog.beagle.name
dog.beagle.microchipID
I want this string and number to be allocated in C and accessible by Lua. So, in C code, the variables might be defined as:
int microchipIDNumber;
char dogname[500];
The C variables need to be updated by assignments in Lua and its value needs to be retrieved by Lua when it is on the right of the equal sign. I have tried the __index and __newindex metamethod concept but everything I try seems to break down when I have 2 dots in the Lua path to the variable. I know I am probably making it more complicated with the 2 dots, but it makes the organization much easier to read in the Lua code. I also need to get an event for the assignment because I need to spin up some hardware when the microchipIDNumber value changes. I assume I can do this through the __newindex while I am setting the value.
Any ideas on how you would code the metatables and methods to accomplish the nesting? Could it be because my previous function declarations are confusing Lua?
The colon operator (:) in Lua is used only for functions. Consider the following example:
meta = {}
meta["__index"] = function(n,m) print(n) print(m) return m end
object = {}
setmetatable(object,meta)
print(object.foo)
The index function will simply print the two arguments it is passed and return the second one (which we will also print, because just doing object.foo is a syntax error). The output is going to be table: 0x153e6d0 foo foo with new lines. So __index gets the object in which we're looking up the variable and it's name. Now, if we replace object.foo with object:foo we get this:
input:5: function arguments expected near ')'
This is the because : in object:foo is syntactic sugar for object.foo(object), so Lua expects that you will provide arguments for a function call. If we did provide arguments (object:foo("bar")) we get this:
table: 0x222b3b0
foo
input:5: attempt to call method 'foo' (a string value)
So our __index function still gets called, but it is not passed the argument - Lua simply attemps to call the return value. So don't use : for members.
With that out of the way, let's look at how you can sync variables between Lua and C. This is actually quite involved and there are different ways to do it. One solution would be to use a combination of __index and __newindex. If you have a beagle structure in C, I'd recommend making these C functions and pushing them into the metatable of a Lua table as C-closures with a pointer to your C struct as an upvalue. Look at this for some info on lua_pushcclosure and this on closures in Lua in general.
If you don't have a single structure you can reference, it gets a lot more complicated, since you'll have to somehow store pairs variableName-variableLocation on the C side and know what type each is. You could maintain such a list in the actual Lua table, so dog.beagle would be a map of variable name to one or two something's. There a couple of options for this 'something'. First - one light user data (ie - a C pointer), but then you'll have the issue of figuring out what that is pointing to, so that you know what Lua type to push in for __index and what to pop out for __newindex . The other option is to push two functions/closures. You can make a C function for each type you'll have to handle (number, string, table, etc) and push the appropriate one for each variable, or make a uber-closure that takes a parameter what type it's being given and then just vary the up-values you push it with. In this case the __index and __newindex functions will simply lookup the appropriate function for a given variable name and call it, so it would be probably easiest to implement it in Lua.
In the case of two functions your dog.beagle might look something like this (not actual Lua syntax):
dog.beagle = {
__metatable = {
__index = function(table,key)
local getFunc = rawget(table,key).get
return getFunc(table,key)
end
__newindex = function(table,key,value)
local setFunc = rawget(table,key).set
setFunc(table,key,value)
end
}
"color" = {
"set" = *C function for setting color or closure with an upvalue to tell it's given a color*,
"get" = *C function for getting color or closure with an upvalue to tell it to return a color*
}
}
Notes about the above: 1.Don't set an object's __metatable field directly - it's used to hide the real metatable. Use setmetatable(object,metatable). 2. Notice the usage of rawget. We need it because otherwise trying to get a field of the object from within __index would be an infinite recursion. 3. You'll have to do a bit more error checking in the event rawget(table,key) returns nil, or if what it returns does not have get/set members.

Resources