Is a parameter name neccesary for virtual method definition in C++? - 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.

Related

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.

passing variable without a name to function

I saw a function written in the following manner:
retVal PreProcessor::TxSlotCB(void *a_pClass, PRE_PARAMS &/*commonParam*/)
{
some code
}
struct PRE_PARAMS
{
uint32_t param1;
uint32_t param2;
};
what is happening in the second parameter? how can it be empty? and is there any way to access to it?
In C++, a formal parameter can be given but anonymous. This means that the actual argument should be given but is not used in the called function.
So it should be given in calling context, it is transmitted, but the called function cannot and does not use it. And the compiler won't give any warnings.
You cannot access it in the body of the function. If you need to access it, change the declaration of the formal parameter to give it some name.
This means that parameter of type PRE_PARAM is not used by this function currently.
So, what happens is when you design a function you decide on the parameters this function would take to fulfill it's purpose.
But later you find that this parameter is not of much significance to this function. However, removing this parameter from function declaration is a tedious job as you have to check for all calls to this function and make sure they confirm to that change.
So, a better way is to not provide the name for argument in function's definition making that parameter redundant.

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.

c function interface question

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.