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.
Related
And what's the difference between
void*(*void)(void*)
and
void*(*voi)(void*)
and when to use it?
well void*(void)(void) doesn't compile, because it tries to declare a function that returns a void* named void and you can't use keywords of the language as names.
you can't declare an int named void either (int void=5; doesn't work of course).
Now voi is a valid identifier and you can name a function voi.
Trying to get at what you're actually asking the difference between.
void(*name)(void); and void(name)(void); is that one declares a function and the other declares a function pointer.
In fact the brackets on the second example don't do anything. void(name)(void); is the same as void name(void);.
However when declaring function pointers the brackets are needed or the * will bind left to the return type.
Anyway, I'm not sure what exactly you're asking, so you're best off searching the site for other questions regarding function pointers. Like this one that also explains why using void(name)(void) can be different from void(name)().
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.
Related to Why does casting a function to a function type that is identical except for return type fail?, I would like to understand, in a fuller way, the distinction between a function's type and a function's signature.
For example, the type of a function must typically be considered when dealing with function pointers, and the type of the function includes the return type of that function.
However, as noted in Mike Seymour's answer to the above-linked question, the signature of a function is different from the type of a function. The signature is certainly used to disambiguate from among potential overloaded functions (noting that the return type of functions does not play a role in identifying unique functions). But, I would now like to understand the relevance and importance of function signatures vs. function types. It occurs to me that the only purpose of function signatures in C++ is to identify overload candidates and/or unique functions in an overload set, during overload resolution.
Am I correct? Is overload resolution the only purpose of function signatures in C++? Or are there any other uses/applications of function signatures, besides (or only indirectly related to) overload resolution?
ADDENDUM For clarity, please note that I am specifically seeking to understand the distinction between the purpose of a function signature and a function type. I.e., I know that a function type is required both for the use of function pointers, and for a compiler/linker's implementation of a calling convention. However, the calling convention is relevant only after overload resolution is complete. I am here asking, specifically, if the only purpose of the function signature (as opposed to type) is for overload resolution.
Am I correct?
As far as I'm concerned, there are other purposes too. Consider that C also has function signatures but doesn't have overloading.
Apart from overloading, the fundamental purpose of function signatures is conforming to the calling convention of a particular platform.
When a function accepts arguments and returns values, the compiler needs to know the type and the size of the arguments in order to pass them correctly to a function. In general, function arguments are pushed onto the stack (this is not a universal rule though, especially on 64-bit architecture systems). Consider the following situation. If you call a function like
foo(42);
how does the compiler know what is the size of the integer value it has to pass to the function? The number 42 can be represented using various bit width, for example as a 1, 2, 4 (or even 8)-byte integer:
00101010
0000000000101010
00000000000000000000000000101010
Now if the function doesn't have a signature which tells that, for instance, the argument is a char (which is 1 byte), or a short (which may be 2 bytes) or an int, which may be 4 bytes, then the compiler has no way of determining the correct size. It means that if it pushes an arbitrary number of bytes to the stack, but the function expects another size, then stack corruption occurs.
Another good example is returning structures (struct). Usually, primitive return values (such as integers and floating-point numbers) are returned in a register; this is generally the EAX register on x86. But what if one wants to write a function returning a struct? if the overall size of the struct is so large that it doesn't fit into a register, the compiler must generate code that pushes the return value onto the stack as opposed to assigning it to a register. So if a function is defined as
int foo()
{
return 1337;
}
or as
struct bar {
int a;
char b[16];
float x;
};
struct bar foo()
{
struct bar ret;
ret.a = 0;
memcpy(&ret.b, "abcdefghijklmno", sizeof(ret.b));
ret.x = 3.1415927;
return ret;
}
different assembly (and machine code) will be generated - the first function that returns an integer will use the EAX register for storing the return value, but the second call will have to use the stack.
The standard mentions that signatures are used for name mangling and linking.
That being said, name mangling is not standarized. The return type is redundant in a function symbol (since there is only one possible return type for a function with a given name and arguments in a valid program, it is not required to differentiate two different symbols), but even then some ABIs do include the return type of a function in the mangled name, probably as a way of double checking that there is no violation of the rule above.
Suppose I have a dll with 2 functions.name of dll="dll1"
f1(int a, int b, int c);
f2(int a);
My program would take the function name ,the dll name and a "list" of parameters as input.
how would i call the appropriate function with its appropriate parameters.
i.e,
if input is
dll1
f1
list(5,8,9)
this would require me to call f1 with 3 parameters
if input was
dll1
f2
list(8)
it would require me to call f2 with one parameter
how would i call the function without knowing the number of parameters in advance.
further clarification:
how do I write code that will call any
function with all its arguments by building the argument list dynamically
using some other source of information
Since the generated code differs based on the number of parameters, you have two choices: you can write some code in assembly language to do the job (basically walk through the parameter list and push each on the stack before calling the function), or you can create something like an array of pointers to functions, one for each number of parameters you care about (e.g., 0 through 10). Most people find the latter a lot simpler to deal with (if only because it avoids using assembly language at all).
To solve the problem in general you need to know:
The calling conventions (those stdcall, cdecl, fastcall, thiscall (btw, the latter two can be combined in MSVC++), etc things) that govern how the functions receive their parameters (e.g. in special registers, on the stack, both), how they return values (same) and what they are allowed to trash (e.g. some registers).
Exact function prototypes.
You can find all this only in the symbol/debug information produced by the compiler and (likely to a lesser extent) the header file containing the prototypes for the functions in the DLL. There's one problem with the header file. If it doesn't specify the calling convention and the functions have been compiled with non-default calling conventions (via a compiler option), you have ambiguity to deal with. In either case you'll need to parse something.
If you don't have this information, the only option left is reverse engineering of the DLL and/or its user(s).
In order to correctly invoke an arbitrary function only knowing its prototype and calling convention at run time you need to construct code analogous to that produced by the compiler when calling this function when it's known at compile time. If you're solving the general problem, you'll need some assembly code here, not necessarily hand-written, run-time generated machine code is a good option.
Last but not least, you need some code to generate parameter values. This is most trivial with numeric types (ints, floats and the like) and arrays of them and most difficult with structures, unions and classes. Creating the latter on the fly may be at least as difficult as properly invoking functions. Don't forget that they may refer to other objects using pointers and references.
The general problem is solvable, but not cheaply. It's far easier to solve a few simple specific cases and maybe avoid the entire problem altogether by rewriting the functions to have less-variable parameters and only one calling convention OR by writing wrapper functions to do that.
You might want to check out the Named Parameter Idiom.
It uses method chaining to basically accomplish what you want.
It solves the problem where you know what a default set of arguments look like, but you only need to customize a few of them and not necessarily in the order they are declared.
If your clients know at compile-time, then can wrap it this way:
template<class Args...>
void CallFunctionPointer(void* pf, Args&&... args)
{
typedef void(*FunctionType)(Args...);
FunctionType* pf2 = (FunctionType*) pf;
(*pf2)(forward<Args>(args)...);
}
Note, if you pass the wrong number of paramters or the wrong type(s) of parameters behaviour is undefined.
Background:
In C/C++ you can cast a function pointer to any signature you want, however if you get it wrong behavior is undefined.
In your case there are two signatures you have mentioned:
void (*)(int)
and
void (*)(int, int, int)
When you load the function from the DLL it is your responsibility to make sure you cast it to the correct signature, with the correct number and types of parameters before you call it.
If you have control over the design of these functions, I would modify them to take a variable number of arguments. It the base type is always int, than just change the signature of all the functions to:
void (*)(int* begin, size_t n);
// begin points to an array of int of n elements
so that you can safely bind any of the functions to any number of arguments.
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.