c function interface question - c++

extern "C" int func(int *, Foo);
This is from a sample code from class. But I don't understand how the interface is working, one with no variable name, the other with no type. How is that going to work?

When declaring functions you don't need to specify a parameter name, just a type. Foo in this case is a type.
extern "C" tells the compiler it should use a C-style symbol, which more or less means it won't be using name mangling (which C++ uses to allow multiple functions share a name, but use different parameter sets or namespaces).

one with no variable name, the other with no type. How is that going to work?
In the function declaration (and even in definition), variable names are optional, And in your case, Foo is a type, it's not a variable name!
The following program is completely valid even though function f mentions no parameter names!
int f(int)
{
cout << "f(int) is called";
}
int main()
{
f(100);
}

This is a function declaration. You don't need to have a variable name.
The 2nd does have a type, it's Foo.

This is just a prototype. That is to say, it's what's needed to call the function, but not the code that says what the function actually does.
All the compiler needs to know to generate the calling code is the types of the arguments of the function, the function name, and the return type. It doesn't need to know the names of the arguments.
The second argument is a Foo. That's not the name, that's the type.

By using extern "C" you can link a C++ program to C functions.
In your example above, it will turn off name mangling for func so that you can link to code compiled by a C compiler.
C++ compilers need name mangling to differentiate between different functions with the same name. Name mangling is the rule according to which C++ changes function names into function signatures before invoking the linker.

Your assumption is not correct: both parameters have their type specified, and none of them has the name specified. In this case Foo is a type (a struct?) already defined somewhere.
That the parameters have no names is not a problem because this is the declaration of a function: it only serves to let the compiler know the signature (number and types of parameters, plus return type) of the function. It doesn't matter how the formal parameters are named (or if they are named at all). That information is only useful if you are about to write the function body.

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

Is a parameter name neccesary for virtual method definition in C++?

Here is the code:
virtual bool myFunction(const Waypoints& /*waypoints*/) {
return false;
}
For my understanding, virtual function is for late / dynamic binding. bool is the return type. const Waypoint& is a constant reference. When it is used to formal parameters, it avoids value copy and forbids being changed by the function.
Now, my question is, shall we need a variable name for the formal parameter of this function somehow? I mean, /*waypoints*/ are simply comments, right? Where are the formal parameters then?
The method has one formal parameter of type const Waypoints&. It is unnamed, because it is not used in the method body. This might make sense, because other implementations of the same method might use it (note that the method is virtual). Whether the name of the parameter /*waypoints*/ is commented out, left there or removed altogether is a matter of taste. Some compilers issue a warning when a formal parameter (that does have a name) is not used in the method body, so this might be the reason it was commented out.
A declaration of a function (member or free) never needs names for parameters (although they can be useful for the reader). A definition of a function only needs names for parameters that are used in the body of the function. You can have different names in different declarations, they are ignored.
Where are the formal parameters then?
There is an parameter of type const Waypoints&. It is unnamed in the definition, which is fine because it is unused.

Unnamed function parameter usage

When read some code I saw this unnamed pointer usage as function parameter. What is meaning of this usage ?
RequestAddListItem(QListWidgetItem*)
used in this line (https://socket.io/blog/socket-io-cpp/)
connect(this,SIGNAL(RequestAddListItem(QListWidgetItem*)),this,SLOT(AddListItem(QListWidgetItem*)));
Declaration:
// in mainwindow.h
Q_SIGNALS:
void RequestAddListItem(QListWidgetItem *item);
This is not a real C++ syntax. SIGNAL() macro will convert it to a string and use it as identifier. It is used to identify the correct signal to bind to, by matching to signals declarations in Q_SIGNALS section. This was a chosen convention to use to omit the argument name in these identifiers. It is a natural decision, given that these names would tend to be meaningless, with signal/slot name being good enough description.
In general, argument names in function declarations are optional, they matter only in function definition, as they are necessary to access the arguments. Technically, they are still optional.
If it's part of a function declaration, it means that it doesn't need to be named yet (e.g. in the header). If it's part of the function's definition, it means the parameter isn't used.
It (the parameter) might need to be declared if this function needs to be an overriding virtual function, a callback that needs to be passed, etc. (i.e. to match some function signature).

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.

Binary compatibility when changing parameter name in C++

I have a question about changing parameter name of a member function.
I have function foo(type iA) then I change to foo(type iB), I think it is bin comp, but I am not sure.
Could you help me to explain the reason? Thanks a lot!
Of course it will be binary compatible because you do not change the type of object. Hence the size stays the same. Name of variable is only for human.
You can actually declare function not giving any names, like:
int funct(void*, int, Object)
When you define it you can use whatever you like
int funct(void* ptr, int something , Object object){return 42;};
It is fine. It also works for class members.
The (I would say main) reason for binary compatibility or incompatibility are the sizes of passed objects. So when you operate on actual binary data, on assembler level no offsets change. If you changed types, arguments would lie in different places in memory, and offsets for them would need to be recalculated. What is important are addresses not aliases or names.
Edits:
For the sake of the completeness.
As #Lightness pointed out, you can also skip names in definition, so the very example I gave could look: int funct(void*, int, Object){return 42;};.
Also regarding #James' comment. I would say that when two objects have the same size, it gets murky. Of course it makes no sense to make such wild conversion from one type to another. However, considering previous example, if you do not use operand it would probably work ... on the assembler level. If sizes differed it would corrupt stack.
However, when I thought how to comment on this problem, I told myself that you ask about c++. So let's look at it from this point of view. I would say that functions are binary compatible when their signature does not change. And names of operands are not part of it in any definition. Function signature is a basis for name mangling and overloading, and the symbol name in the final binary object.
The names of the arguments is just for you to distinguish the arguments. You can have different names in a function declaration and the functions definition.
So this is okay:
void foo(int bar); // Declare function
...
// Define function
void foo(int bibibibibi)
{
...
}
The declaration and definition above is for the same function. C++ does not override or overload functions based on argument names, only argument types.
The compiler does not store the names of arguments (or other variable) except as debug info. The actual generated code have no information about the variable names.