determining function declaration, definition and call - c++

I came across a question regarding writing a code to determine unused functions in C++. We can use different data structures to determine unused functions. But before that, we need to parse the code. I have question related to parsing part, how we can differentiate functions declaration and definition and function-calls?
Like,
//function declaration without argument
fun1 ();
//function definition
fun1 () {
// code goes here
}
main () {
fun1 ();
}
Above declaration and call is looks same where as definition part is little bit different from declaration and call.
Other than above scenario, there are multiple scenario for calling a function and functions scope, like two classes having function with same name one function get called within member function (i.e. no explicit calling object required) OR function call using object so, need to understand object's type first to determine which function is actually called.
How can parsing implemented efficiently? How many parsing will required in above scenario?

This is how you can distinguish them:
//function definition
return_type fun1 (args) {
// code goes here
}
Note that function definition has a "return type" before the function name.
Also, note that a function declaration looks exactly the same as its definition. You don't actually need to distinguish them until you see either ; or {. That is the point in which you make the decision whether its a declaration or definition. In your particular application, you don't really care about it because you don't care what the function actually does.
Unfortunately for you, C++ is complicated. To determine which functions are useless, you actually need at least a basic semantic analysis. This includes at least the type system.
What is worse, is that some function may not necessarily be called directly, but through a virtual function. So your static analysis of the code shows only the parent's function getting called, while in reality it's the child's.

Related

calling a function inside header file [duplicate]

I have couple questions regarding some C++ rules.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2 in the code below) i.e. this works:
bool b = testclass1::foo<int>(2);
whereas this doesn't: - (it doesn't even compile - compiler throws that this is function redeclaration)
testclass1::foo<int>(2);
C++ complains that it is a function redeclaration. Is that so?
This line:
bool b = testclass1::foo<int>(2);
gets called first before anything else. Is this because static methods get created always first before anything else in C++?
Where can I find those rules? I have a few C++ books at home, so if someone would be kind enough to either point out a book (and chapter or page) or direct me to a website I would greatly appreciate it.
Here below is the sample (partial) code that I tested at home with Visual Studio 2008:
class testclass1
{
public:
testclass1(void);
~testclass1(void);
template<class A> static bool foo(int i)
{
std::cout <<"in static foo";
return true;
}
};
namespace test2
{
class testclass2
{
public:
testclass2(void);
~testclass2(void);
};
bool b = testclass1::foo<int>(2);
}
EDIT:
A few people mentioned that I need to call this inside the function and this will work without any problem.
I understand that; the only reason I asked this question is because I saw this code somewhere (in someone's elses project) and was wondering how and why this works. Since I never really seen anyone doing it before.
Also, this is used (in multiple places) as a way to call and instantiate a large number of classes like this via those function calls (that are outside). They get called first before anything else is instantiated.
C++ is not Python. You write statements in functions and execution starts from the main method. The reason bool b = ... happens to work is that it's defining the global variable b and the function call is merely the initialization expression.
Definitions can exist outside functions while other statements can only exist inside a function body.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2)
Your declaration of b is not inside a function, so you are declaring a global variable. If you were inside a function's scope, your second statement would work, but outside a function it makes no sense.
This also answers your second question.
Of course, you wouldn't be allowed to call it this way (i.e. not as a method of an object) if it weren't a static member function.
You can find the rules on e.g. Koenig lookup and template in the standard documentation -- good luck with navigating that! You're not mentioning which compiler you are testing, but I'm not entirely sure it's compliant!
As Mehrdad points out, you're declaring and initializing a global variable within the test2 namespace: this has nothing to do with static methods.
if you write this inside a function like below then it works without a problem. As mentioned above, you need to call these functions from within a function unless you are using the function to initialize a global variable ...
int main()
{
testclass1::foo<int>(2);
return 0;
}
1. First, a helpful correction: you said "...when I include the return type". I think you might be misunderstanding what the <int> part of testclass1::foo<int>(2) does. It doesn't (necessarily) specify the return type, it just provides a value for the template argument "A".
You could have chosen to use A as the return type, but you have the return type hard-coded to "bool".
Basically, for the function as you have written it you will always need to have the <> on it in order to call it. C++ does allow you to omit the <args> off the function when the type can be deduced from the function arguments; in order to get it to do that you have to use the type argument A in your function arguments. For instance if you declared the function this way instead then you could call it without the <>:
template<class A> static bool foo(A i);
In which case it you could call "foo(2)" and it would deduce A to be "int" from the number two.
On the other hand there isn't any way to make it deduce anything based on what you assign the function to. For template argument deduction it only looks at the arguments to the function, not what is done with the result of calling the function. So in:
bool b = testclass1::foo(2);
There is no way to get it to deduce "bool" from that, not even if you made A the return type.
So why doesn't the compiler just tell you "you needed to use <> on the function"? Even though you declared foo once as a template function, you could have also overloaded it with a non-template version too. So the compiler doesn't just automatically assume that you're trying to call a template function when you leave the <> off the call. Unfortunately having NOT assumed you were calling template-foo and not seeing any other declaration for foo, the compiler then falls back on an old C style rule where for a function that takes an int and returns an int, in a very old dialect of C you didn't need to declare that kind of before using it. So the compiler assumed THAT was what you wanted - but then it notices that template-foo and old-crufty-C-foo both take an int parameter, and realizes it wouldn't be able to tell the difference between them. So then it says you can't declare foo. This is why C++ compilers are notorious for giving bad error messages - by the time the error is reported the compiler may have gone completely off the rails and be talking about something that is three or four levels removed from your actual code!
2. Yes you're exactly right.
3. I find that the C++ references and whitepapers that IBM makes available online are the most informative. Here's a link to the section about templates: C++ Templates

Are function prototypes necessary for C++?

Basically, I am reading through this book right here and in Section 1.6: Some Differences between C and C++ it is stated:
Another subtle difference between C and C++ is that in a C++ program,
all functions must be prototyped.
I am sure that this is not true from all the C++ programs that I have written. Is this only true for some versions of C++? Is it also true for C?
It has been true of C++ since the beginning (although in C++ it's just called a "declaration", not a "prototype").
As C existed decades ago, it allowed you to call a function without declaring it. You could, however, declare a function if you wanted to--usually to tell the compiler that it had a return type different from what the compiler would deduce on its own. So, in C a function declaration looks something like this:
long f();
Note that empty parens there. That's what separates a function "declaration" from a function "prototype" (though a prototype is basically a superset of a declaration, so a prototype also declares the function in question). A prototype always has something inside the parens to indicate the number and type of parameters the function accepts, on this general order:
short g(int a, double b);
If it doesn't accept any parameters, you have to put in void to indicate that:
int h(void);
If you leave the parens empty, that (as noted above) means it's a function declaration instead of a prototype--and that means you're telling the compiler the function's return type, but you're not telling it anything about the number or type of parameters.
C++ (since before it was called C++, if I recall correctly) has only had one concept instead of the two in C. In C++ every function must be declared--and a declaration always includes the number of parameters, and the type of each. This is absolutely necessary to support (for one obvious example) function overloading, where the correct function to call is determined from the number and types of arguments you pass in the call.
A function definition in C++ also acts as a function declaration. Every function must be declared, but the declaration doesn't have to be separate from the definition.
In reasonably modern C, you normally get pretty much the same--that is, a "new" (i.e., not ancient) type function definition also acts as a prototype for that function. As C was originally defined, it included a syntax for a function definition that looked like this:
int f(a, b, c)
int a;
short b;
long c;
{
// function body here
}
This defines the function, but the compiler treats it only as a function declaration, not a prototype--that is, it tells the compiler the return type, but the number and types of parameters (even though they're specified) are not used by the compiler in the same way they would be with a function prototype. C++ has never used or supported this style of function definition though.

How to understand _Function_class_(name) in C++

I am reading some VC++ code and see some usage of this function annotation _Function_class_(name).
According to MSDN:
The name parameter is an arbitrary string that is designated by the user. It exists in a namespace that is distinct from other namespaces. A function, function pointer, or—most usefully—a function pointer type may be designated as belonging to one or more function classes.
However, I still couldn't understand in what scenario this should be used, and what exactly it means to a function. Can someone please explain a bit more?
Thank you
This annotation allows you to restrict the set of functions that may be used in a given context. Generally, when using pointers to functions and references to functions, you can bind those pointers and references to refer to any function that has the correct type.
There may be cases where you want only a restricted set of functions of that type to be usable in a given context, or you may want to ensure that someone really, really means to use a particular function in that context. For example, if you take a pointer to a callback function, and there are restrictions on what may be done inside of that callback, you might use this attribute to help developers to think about those restrictions when passing new functions as callbacks.
Consider the following example: f is annotated as being of the special_fp_type class of functions. g is of the same type, so it is usable in the same contexts as f, but it is not annotated as being of the special_fp_type class of functions:
#include <sal.h>
typedef _Function_class_(special_fp_type) void (*special_fp_type)();
void _Function_class_(special_fp_type) f() { }
void g() { }
void call_special_function(special_fp_type) { }
int main()
{
call_special_function(f);
call_special_function(g);
}
If you compile this with /analyze, you'll get a helpful warning for the usage of g here, telling you that it was not part of the expected class of functions:
warning C28023: The function being assigned or passed should have a _Function_class_ annotation for at least one of the class(es) in: 'special_fp_type':
Frequently, when only one function class is in use, this is caused by not declaring a callback to be of the appropriate type.

pointers-inline meaning? [duplicate]

This question already has answers here:
what is/are the purpose(s) of inline?
(9 answers)
Closed 8 years ago.
I have come across this while reading a program in C++
inline Controller* Get_it() { // ... bla bla
I don't understand what this means. Does this imply the definition of Get_it function? I have searched for files where Get_it function is defined, but didn't find it. I think that the syntax a* b means that b is pointer to point to objects of structure a, but there is no stucture Controller. There is though a class Controller defined somewhere else.
Thank you in advance people. I am new to C++ and I am trying to understand.
The function Get_it returns a Controller*. That's a pointer to a Controller, which is a type that must be declared somewhere above this point in the translation unit. The function is marked inline which is a hint to the compiler that it can inline the code, basically copying the function body into every place it is called from.
These two things are separate. The pointer is not inline, the function is.
The keyword inline affects what it being defined, and is only
applicable to functions. Formally, it allows (and in fact
requires) multiple definitions of the function. It is also
a "hint" to the compiler that it should try to generate the code
for the function directly at the call site, rather than to
generate a call elsewhere. (The motivation for the formal
definition is that the compiler typically cannot generate the
code inline unless it has access to the definition.)
First, you should get yourself a good book on C++. Secondly, that is a pointer to a Controller object (a class in memory). It is returned by the function and the function is defined inline, meaning that it will be copied entirely to the callsite wherever it is called.
The inline word is a suggestion to the compiler to do inlining where sensible, but because you seem to indicate the function is defined inside the class declaration, it will be inlined by the compiler automagically.
The inline keyword doesn't apply to the pointer (the return value of the function), but to the function itself. So here you declare (and define) an inline function which returns a pointer-to-Controller.
The inline keyword defines an method as inline1, no matter where it get's implemented. The signature above means, that the function Get_it() returns an pointer to an Controller object. The function itself is inline.
1 Inline means, that the method get's not addressed through an vtbl, but get's directly allocated in the object's memory, so that there is no indirection when calling the method on an object instance, but the object instance itself grows in memory size.

C++ - calling methods from outside the class

I have couple questions regarding some C++ rules.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2 in the code below) i.e. this works:
bool b = testclass1::foo<int>(2);
whereas this doesn't: - (it doesn't even compile - compiler throws that this is function redeclaration)
testclass1::foo<int>(2);
C++ complains that it is a function redeclaration. Is that so?
This line:
bool b = testclass1::foo<int>(2);
gets called first before anything else. Is this because static methods get created always first before anything else in C++?
Where can I find those rules? I have a few C++ books at home, so if someone would be kind enough to either point out a book (and chapter or page) or direct me to a website I would greatly appreciate it.
Here below is the sample (partial) code that I tested at home with Visual Studio 2008:
class testclass1
{
public:
testclass1(void);
~testclass1(void);
template<class A> static bool foo(int i)
{
std::cout <<"in static foo";
return true;
}
};
namespace test2
{
class testclass2
{
public:
testclass2(void);
~testclass2(void);
};
bool b = testclass1::foo<int>(2);
}
EDIT:
A few people mentioned that I need to call this inside the function and this will work without any problem.
I understand that; the only reason I asked this question is because I saw this code somewhere (in someone's elses project) and was wondering how and why this works. Since I never really seen anyone doing it before.
Also, this is used (in multiple places) as a way to call and instantiate a large number of classes like this via those function calls (that are outside). They get called first before anything else is instantiated.
C++ is not Python. You write statements in functions and execution starts from the main method. The reason bool b = ... happens to work is that it's defining the global variable b and the function call is merely the initialization expression.
Definitions can exist outside functions while other statements can only exist inside a function body.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2)
Your declaration of b is not inside a function, so you are declaring a global variable. If you were inside a function's scope, your second statement would work, but outside a function it makes no sense.
This also answers your second question.
Of course, you wouldn't be allowed to call it this way (i.e. not as a method of an object) if it weren't a static member function.
You can find the rules on e.g. Koenig lookup and template in the standard documentation -- good luck with navigating that! You're not mentioning which compiler you are testing, but I'm not entirely sure it's compliant!
As Mehrdad points out, you're declaring and initializing a global variable within the test2 namespace: this has nothing to do with static methods.
if you write this inside a function like below then it works without a problem. As mentioned above, you need to call these functions from within a function unless you are using the function to initialize a global variable ...
int main()
{
testclass1::foo<int>(2);
return 0;
}
1. First, a helpful correction: you said "...when I include the return type". I think you might be misunderstanding what the <int> part of testclass1::foo<int>(2) does. It doesn't (necessarily) specify the return type, it just provides a value for the template argument "A".
You could have chosen to use A as the return type, but you have the return type hard-coded to "bool".
Basically, for the function as you have written it you will always need to have the <> on it in order to call it. C++ does allow you to omit the <args> off the function when the type can be deduced from the function arguments; in order to get it to do that you have to use the type argument A in your function arguments. For instance if you declared the function this way instead then you could call it without the <>:
template<class A> static bool foo(A i);
In which case it you could call "foo(2)" and it would deduce A to be "int" from the number two.
On the other hand there isn't any way to make it deduce anything based on what you assign the function to. For template argument deduction it only looks at the arguments to the function, not what is done with the result of calling the function. So in:
bool b = testclass1::foo(2);
There is no way to get it to deduce "bool" from that, not even if you made A the return type.
So why doesn't the compiler just tell you "you needed to use <> on the function"? Even though you declared foo once as a template function, you could have also overloaded it with a non-template version too. So the compiler doesn't just automatically assume that you're trying to call a template function when you leave the <> off the call. Unfortunately having NOT assumed you were calling template-foo and not seeing any other declaration for foo, the compiler then falls back on an old C style rule where for a function that takes an int and returns an int, in a very old dialect of C you didn't need to declare that kind of before using it. So the compiler assumed THAT was what you wanted - but then it notices that template-foo and old-crufty-C-foo both take an int parameter, and realizes it wouldn't be able to tell the difference between them. So then it says you can't declare foo. This is why C++ compilers are notorious for giving bad error messages - by the time the error is reported the compiler may have gone completely off the rails and be talking about something that is three or four levels removed from your actual code!
2. Yes you're exactly right.
3. I find that the C++ references and whitepapers that IBM makes available online are the most informative. Here's a link to the section about templates: C++ Templates