passing variable without a name to function - c++

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.

Related

Nameless void pointer as parameter?

This is the signature of a function in VirtualBox:
static DECLCALLBACK(void) svcCall (void *,
VBOXHGCMCALLHANDLE callHandle,
uint32_t u32ClientID,
void *pvClient,
uint32_t u32Function,
uint32_t cParms,
VBOXHGCMSVCPARM paParms[])
I don't know what the first parameter, void * is supposed to mean and how one would work with it.
What is its use?
It's probably not used in that implementation. Leaving it without a name avoids the compiler warning
unused parameter xyz
To know what this parameter means you should have a look at the callback functions declaration, rather than an arbitrary implementation.
what the first parameter, void * is supposed to mean
It means that the first parameter is of type void*. Not giving the parameter a name implies that the parameter is unused on purpose.
how one would work with it
One doesn't, becase one can't work with it.
What is its use?
If you want a definitive answer, you should ask the VirtualBox developer that wrote it. I'm not them, but I can give you a guess:
Perhaps, the function is used as a callback. And the callback is specified to have a void pointer as the first parameter. But this particular callback does not need the value of the void pointer.

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.

Disabling "bad function cast" warning

I'm receiving the following warning:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
This is because I need to pass as argument a member function instead of an ordinary function. But the program is running correctly.
I'd like to disable this warning (Wno-bad-function-cast doesn't work for C++) or to implement a different way to pass a member function.
No. Take this warning seriously. You should rather change your code to handle this scenario.
Pointer to member function(void (MyClass::*)(byte)) and normal function pointer (void (*)(byte)) are entirely different. See this link. You cannot cast them just like that. It results in undefined behavior or crash.
See here, how they are different:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
Now you may feel that, foo(byte) and MyClass::foo(byte) have same signature, then why their function pointers are NOT same. It's because, MyClass::foo(byte) is internally resolved somewhat as,
void foo(MyClass* const this, byte);
Now you can smell the difference between them.
Declare pointer to member function as,
void (MyClass::*ptr)(byte) = &MyClass::foo;
You have to use this ptr with the object of MyClass, such as:
MyClass obj;
obj.*ptr('a');
You can't pass a function that takes two arguments to a place that expects a function that takes one. Can't be done, forget about it, period, end of story. The caller passes one argument to your function. It doesn't know about the second argument, it doesn't pass it to your function, you can't make it do what you want however hard you try.
For the very same reason you can't pass a non-static member function where a regular function is expected. A member function needs an object to operate on. Whatever code calls your function doesn't know about the object, there's no way to pass it the object, and there's no way to make it use the right calling sequence that takes the object into account.
Interfaces that take user's functions, without taking additional data that the user might want to pass to his function, are inherently evil. Look at the qsort() function from the C standard library. That's an example of an evil interface. Suppose you want to sort an array of string according to some collation scheme defined externally. But all it accepts is a comparison function that takes two values. How do you pass that collation scheme to your comparison function? You can't, and so if you want it working, you must use an evil global variable, with all the strings attached to it.
That's why C++ has moved away from passing function pointers around, and towards function objects. Function objects can encapsulate whatever data you want.
Also, this may be helpful
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};

about argument to member function

Will adding an argument to member function gonna change the behavior of the function?
Need help about this concept.
The behavior won't change if you only add an argument to the prototype of the function.
However you will have to change all the call to this function since the prototype changed, this isn't the same function anymore.
And sincerely, I don't see the point of adding an argument if you don't modify the code afterward.
You'll need to give us more information. Like an example. But say you add a new argument (and provide a default), and now argument will be "constructed" and destructed everywhere the member function was called. So it's possible that that in itself has side-effects (e.g. print to console on creationg and destruction).

Function argument already initialized in function declaration C++

So here's my question in the function declaration there is an argument and it is already initialized to a certain value. What are the procedures to call this function and use that default value, or is it just a way to document code, telling other programmers what you expect them to use as a value for the parameter? Thank you.
enum File
{
XML = 0,
PDF = 1,
};
Char *SetSection(const File = XML);
If I understand your question correctly, simply calling SetSection with no parameters will do.
SetSection();
The above call gets translated (for lack of a better term) to:
SetSection(XML);
It means that the function can be called without parameters in which case the default value, XML, will be used.
In this case, File is a default argument. Calling SetSection() without arguments will set the File argument to the default value specified in the declaration.
If you call
SetSection();
It will call SetSection(XML) instead.
This is why the optional parameters have to be at the end of all parameters. If you don't provide enough parameters, it will use the default.
XML is the standard parameter.
You can call it with SetSection(); (But SetSection(XML) or SetSection(PDF) are valid, too).
What you are seeing in the declaration is a default argument value.
If you call SetSection(); it is the same as calling SetSection(XML);
You can also call SetSelection(PDF); or use any other valid parameter to override the default.
You may also be seeing the result of an incremental development which started with the function having no parameter and calls to the function scattered throughout the code. Then the alternative file type of PDF was introduced, but the prototype was changed to have a default value, which meant not having to change the existing call site.