i have a function like
void printMe (void *i)
{
printf("%d", i);
}
where i want to pass a void pointer and print it to screen.
The above example is fine if the i is integer, float or double but crashes if i is a char. There is no overloading in C like i usually use in C++.
So the question is this, can we create a function in C that will print the element that is it's parameter, and if yes how is this possible because it totally eludes me at this moment.
Q1: So the question is this, can we create a function in C that will print the element that is it's parameter
A: Not in the way you want. You will have to pass information to the function, telling it the type of data you're passing.
Q2: and if yes how is this possible because it totally eludes me at this moment.
A: It's eluding you because it can't be done. There is no metadata associated with a void* that the compiler or runtime can use to figure out they type it's pointing to. You need to either
pass a structure that contains a
pointer and information about what
the pointer points to (e.g. an
enum).
pass an extra parameter with
information about what the pointer
points to
As the code stands the only thing you can print here is the address that i points to.
A void pointer points to raw data, printf assumes you know what data type you're printing, it has no intelligence and cannot "figure it out" for you.
It's that simple.
What you can do is pass type information to the function, but then you end up with something very like printf it's self, where you pass a formatting string containing type information about the data in the following arguements.
Hope this helps.
Also . . . "There is no overloading in C like i usually use in C++"
Even in c++ the overloading happens at compile time, and here there's no way for the compiler to know what data will be passed to that function, so even though you're used to overloading, it would never work like this (e.g. try this same thing using printf, but compile it with a C++ compiler, you'll get exactly the same results).
Actually try
cout << i;
in the function above, and it will give you the address i points to, not the "value" of i.
You'd need to cast i and derference it before you could get it's value
cout << *(int*)i;
So, to get the above working in C++ you'd need to have lots of overloaded functions (or a template function, which is really the same thing, except the compiler rolls the functions for you) e.g. overloaded functions
printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}
In c you just need to give those functions specific names
printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}
For a start, you're printing the pointer, not what it points to. To print the actual contents, you need to pass *i to printf, not i.
If you really want to do this, one solution is:
void printMe (void *p, int typ) {
switch(typ) {
case TYP_INT: printf("%d", *((int*)p)); break;
case TYP_CHR: printf("%c", *((char*)p)); break;
/* and so on ... */
}
}
So the question is this, can we create a function in C that will print the element that is it's parameter
Yes, we can. Such a function is already part of the standard library - it's called printf ;)
As there is no compile-time function overloading in C, you somehow have to supply the type of the arguments at runtime. The printf format string can be used to do this, so there's really no reason to build your own wrapper function when there's already a working solution.
If you are trying to print out the pointer value, the correct usage is printf("%p", i);. The 'd' specifier is for integers, and the 'p' is for pointers. It's your responsibility to get these correct, and bad things can happen if you mix them up.
I don't know why this would fail for a char * and not an int *, and it is possible you've got other problems causing this. If it still fails with %p, something else got messed up. See if you can install some sort of memory monitor software to check for dangling pointers or double free()s, because at that point the smart money's that you've corrupted memory somewhere.
Related
I know the following is an example of pass by reference in C++, input is passed as a reference:
void add(int &input){
++input;
}
I also know pass by reference is not available in C. My question is, does the above syntax mean something else in C (i.e pass by value or something), or is it meaningless?
Trying to compile it in C gives this error:
error: parameter name omitted
does the above syntax mean something else in C?
No, it does not. It's not valid C at all.
The & operator means two things in C. The binary one is bitwise "and", and the unary is "address of". You cannot use it in declarations.
C++ chose this for reference variable for two reasons. The first is that since it is not valid C, it will not collide with existing C code. When C++ came, they focused pretty hard on making C++ backwards compatible with C. In later versions of C++, the backwards compability with C is not a very high priority. To a large degree, this is because C++ was a fork of a pretty early version of C, and since then both languages have evolved somewhat independently. For instance C99 added (but it was removed later) variable length arrays, which were never added to C++. Another example is designated initializers.
The other reason is that the meaning of the operator is pretty similar. You can interpret it as "instead of forcing the caller to send the address, I will take the address of whatever he is sending". They simply just moved the & to the function prototype instead of the function call.
And yes, there are a few other differences between pointers and references too
A reference must be initialized. (Assigned upon declaration)
A reference cannot be reassigned to "point" to another object.
A reference must always "point" at an object. It cannot be NULL.
There is one danger with references. In C, you can be certain that a function will never change the variables you send as arguments to a function unless you're sending the address to them. This C code:
int main(void)
{
int a = 42;
foo(a);
printf("%d\n", a);
}
will ALWAYS print "42", no matter how the function foo is defined. Provided that the code compiles and there's no weird undefined behavior. In C++, you don't have that guarantee.
No, it is simply invalid syntax in C.
That is actually one of the reasons that C++ picked this syntax for the feature: it wouldn't change the meaning of any existing C code.
While C does not have pass by reference (and the code will produce compile error), you can get something closer by following the rules:
In the prototype, replace & with * const (reference cannot be reassigned).
In the body, replace reference to varname with (*varname)
When calling the method, replace arg with &(arg).
void add (int *const in)
{
++(*in) ; // increment
(*in) = 5 ; // assign
int x = *in ; // Copy value
}
does the above syntax mean something else in C (i.e pass by value or something), or it's meaningless?
It is meaningless. The program is syntactically ill-formed .
In my University's C programming class, the professor and subsequent book written by her uses the term call or pass by reference when referring to pointers in C.
An example of what is considered a 'call by reference function' by my professor:
int sum(int *a, int *b);
An example of what is considered a 'call by value function' by my professor:
int sum(int a, int b);
I've read C doesn't support call by reference. To my understanding, pointers pass by value.
Basically, is it incorrect to say pointers are C's way of passing by reference? Would it be more correct to say you cannot pass by reference in C but can use pointers as an alternative?
Update 11/11/15
From the way my question originated, I believe a debate of terminology has stemmed and in fact I'm seeing two specific distinctions.
pass-by-reference (the term used mainly today): The specific term as used in languages like C++
pass-by-reference (the term used by my professor as a paradigm to explain pointers): The general term used before languages like C++ were developed and thus before the term was rewritten
After reading #Haris' updated answer it makes sense why this isn't so black and white.
you cannot pass by reference in C but can use pointers as an alternative
Yup, thats correct.
To elaborate a little more. Whatever you pass as an argument to c functions, it is passed by values only. Whether it be a variable's value or the variable address.
What makes the difference is what you are sending.
When we pass-by-value we are passing the value of the variable to a function. When we pass-by-reference we are passing an alias of the variable to a function. C can pass a pointer into a function but that is still pass-by-value. It is copying the value of the pointer, the address, into the function.
If you are sending the value of a variable, then only the value will be received by the function, and changing that won't effect the original value.
If you are sending the address of a variable, then also only the value(the address in this case) is sent, but since you have the address of a variable it can be used to change the original value.
As an example, we can see some C++ code to understand the real difference between call-by-value and call-by-reference. Taken from this website.
// Program to sort two numbers using call by reference.
// Smallest number is output first.
#include <iostream>
using namespace std;
// Function prototype for call by reference
void swap(float &x, float &y);
int main()
{
float a, b;
cout << "Enter 2 numbers: " << endl;
cin >> a >> b;
if(a>b)
swap(a,b); // This looks just like a call-by-value, but in fact
// it's a call by reference (because of the "&" in the
// function prototype
// Variable a contains value of smallest number
cout << "Sorted numbers: ";
cout << a << " " << b << endl;
return 0;
}
// A function definition for call by reference
// The variables x and y will have their values changed.
void swap(float &x, float &y)
// Swaps x and y data of calling function
{
float temp;
temp = x;
x = y;
y = temp;
}
In this C++ example, reference variable(which is not present in C) is being used. To quote this website,
"A reference is an alias, or an alternate name to an existing variable...",
and
"The main use of references is acting as function formal parameters to support pass-by-reference..."
This is different then the use of pointers as function parameters because,
"A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address."
So, essentially when one is sending address and receiving through pointers, one is sending the value only, but when one is sending/receiving a reference variable, one is sending an alias, or a reference.
**UPDATE : 11 November, 2015**
There has been a long debate in the C Chatroom, and after reading comments and answers to this question, i have realized that there can be another way to look at this question, another perspective that is.
Lets look at some simple C code
int i;
int *p = &i;
*p = 123;
In this scenario, one can use the terminology that, p's value is a reference to i. So, if that is the case, then if we send the same pointer (int* p) to a function, one can argue that, since i's reference is sent to the function, and thus this can be called pass-by-reference.
So, its a matter of terminology and way of looking at the scenario.
I would not completely disagree with that argument. But for a person who completely follows the book and rules, this would be wrong.
NOTE: Update inspired by this chat.
Reference is an overloaded term here; in general, a reference is simply a way to refer to something. A pointer refers to the object pointed to, and passing (by value) a pointer to an object is the standard way to pass by reference in C.
C++ introduced reference types as a better way to express references, and introduces an ambiguity into technical English, since we may now use the term "pass by reference" to refer to using reference types to pass an object by reference.
In a C++ context, the former use is, IMO, deprecated. However, I believe the former use is common in other contexts (e.g. pure C) where there is no ambiguity.
Does C even have ``pass by reference''?
Not really.
Strictly speaking, C always uses pass by value. You can simulate pass by reference yourself, by defining functions which accept pointers and then using the & operator when calling, and the compiler will essentially simulate it for you when you pass an array to a function (by passing a pointer instead, see question 6.4 et al.).
Another way of looking at it is that if an parameter has type, say, int * then an integer is being passed by reference and a pointer to an integer is being passed by value.
Fundamentally, C has nothing truly equivalent to formal pass by reference or c++ reference parameters.
To demonstrate that pointers are passed by value, let's consider an example of number swapping using pointers.
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
int ptemp;
printf("Before swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
temp = pnum1;
pnum1 = pnum2;
pnum2 = ptemp;
printf("After swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Instead of swapping numbers pointers are swapped. Now make a function for the same
void swap(int *pnum1, int *pnum2)
{
int *ptemp = pnum1;
pnum1 = pnum2;
pnum2 = temp;
}
int main(void)
{
int num1 = 5;
int num2 = 10;
int *pnum1 = &num1;
int *pnum2 = &num2;
printf("Before swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
swap(pnum1, pnum2);
printf("After swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Boom! No swapping!
Some tutorials mention pointer reference as call by reference which is misleading. See the this answer for the difference between passing by reference and passing by value.
From the C99 standard (emphasis mine):
6.2.5 Types
20 Any number of derived types can be constructed from the object and function types, as
follows:
...
— A pointer type may be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’’. A pointer type is a complete object type.
Based on the above, what your professor said makes sense and is correct.
A pointer is passed by value to functions. If the pointer points to a valid entity, its value provides a reference to an entity.
"Passing by reference" is a concept. Yes, you are passing the value of a pointer to the function, but in that instance the value of that pointer is being used to reference the variable.
Someone else used a screwdriver analogy to explain that it is wrong to refer to the passing of pointers as passing by reference, saying that you can screw a screw with a coin but that that doesn't mean you would call the coin a screw driver. I would say that is a great analogy, but they come to the wrong conclusion. In fact, while you wouldn't claim a coin was a screwdriver, you would still say that you screwed the screw in with it. i.e. even though pointers are not the same as c++ references, what you are using them to do IS passing by reference.
C passes arguments by value, period. However, pointers are a mechanism that can be used for effectively passing arguments by reference. Just like a coin can be used effectively as a screw driver if you got the right kind of screw: some screws slit are even chosen to operate well with coins. They still don't turn the coins into actual screw drivers.
C++ still passes arguments by value. C++ references are quite more limited than pointers (though having more implicit conversions) and cannot become part of data structures, and their use looks a lot more like the usual call-by-reference code would look, but their semantics, while very much catered to match the needs of call-by-reference parameters, are still more tangible than that of pure call-by-reference implementations like Fortran parameters or Pascal var parameters and you can use references perfectly well outside of function call contexts.
Your professor is right.
By value , it is copied.
By reference, it is not copied, the reference says where it is.
By value , you pass an int to a function , it is copied , changes to the copy does not affect the original.
By reference , pass same int as pointer , it is not copied , you are modifying the original.
By reference , an array is always by reference , you could have one billion items in your array , it is faster to just say where it is , you are modifying the original.
In languages which support pass-by-reference, there exists a means by which a function can be given something that can be used to identify a variable know to the caller until the called function returns, but which can only be stored in places that won't exist after that. Consequently, the caller can know that anything that will be done with a variable as a result of passing some function a reference to it will have been done by the time the function returns.
Compare the C and C# programs:
// C // C#
int x=0; int x=0;
foo(&x); foo(ref x);
x++; x++;
bar(); bar();
x++; x++;
boz(x); boz(x);
The C compiler has no way of knowing whether "bar" might change x, because
foo() received an unrestricted pointer to it. By contrast, the C# compiler
knows that bar() can't possibly change x, since foo() only receives a
temporary reference (called a "byref" in .NET terminology) to it and there
is no way for any copy of that byref to survive past the point where foo()
returns.
Passing pointers to things allows code to do the same things that can be done with pass-by-ref semantics, but pass-by-ref semantics make it possible for code to offer stronger guarantees about things it won't do.
I'm on programming project 4 from chapter 19 of C programming, A Modern Approach. My code works but I get this warning trying to pass a function returning a void * parameter to printf with conversion specifier %s.
format %s expects argument of type char *, but argument 2 has type void * [-Wformat=]
I can easily get rid of the warning by casting the return type of the function to char *, like
printf("%s\n", (char *) function(param));
but I just want to know why this necessary since type void * is casted to another pointer type automatically.
Compiler is very right to complain in this case.
As per your logic itself, the function returning void * could return a structure pointer casted to void *, but then, %s won't be able to print that, isn't it?
So, if you know what you're doing, you can cast the result, for this case.
Also, as others pointed out, maybe it's worthy to mention that, this warning has nothing to do with the standard specification, as in the standards, there is no restriction of the type of the arguments. (Borrowing Mr. #WhozCraig's words) This warning is basically due to an additional layer of type-checking entirely performed by compiler on it's own, enabled by -Wformat flag in gcc .
As far as the pure language is concerned (not the standard library and its expectations, the actual formal language) you can push anything you want on that argument list (including something utterly incoherent in relating to the requirements of a %s format specifier of some library routine). Of course, unless whatever you pushed ultimately is, in fact, the address of a nullchar terminated sequence of char, printf itself will trapes into undefined behavior at your behest.
The warning you're receiving is based on an additional layer of api-checking within the compiler, not some violation of the language itself. That api checking is matching format specs with types of presented arguments for frequently-used standard library apis such as printf, scanf, etc. Could the author of that warning-check been a little more forgiving and ignore void* arguments for specs expecting pointer-types? Certainly, but the point of the check-feature would dwindle pretty rapidly were that the case. Consider this:
int a = 0;
void *b = &a;
printf("%s\n", b);
If that api-check feature is going to be worth any salt at all it had better bark about that mismatched type, because as far as the language itself is concerned, there is nothing wrong with this code. And that has nothing to do with what evil I just requested it do. As far as the language is concerned, printf is simply this:
int printf(char *format ...);
And the call I setup certainly fulfills that (bad for me, and thankfully, the api-checks of my modern compiler will let me know soon enough there may be a problem).
A pointer is a variable which points to a single memory location.
The number of bytes pointed by the pointer depends on the type of the pointer. So if it is int* then it is interpreted as 4 bytes,if it is a char* it is interpreted as 1 byte.
A void* has no type. So the compiler cant dereference this pointer. So in order for the compiler to understand the memory to be dereferenced we need typecasting here.
The printf function is declared as something like this:
int printf(char *format ...);
Here ... denotes any additional arguments the caller supplied (that is, your string you wanted to print). When printf examines these additional parameters, it uses some low-level code, which has no type safety.
This code cannot determine that the parameter has type void*, and cast it to char* automatically. Instead, if the binary representation of void* and char* is the same, the parameter can be extracted from the ... part without regard to its actual type. If the representation is different, the low-level code will try to print an incorrect value (and probably crash).
Representation of void* and char* is the same for all platforms that I know of, so it's probably safe (if you trust me, that is - please don't!). However, if you compile with gcc -Wall, as some people recommend, all warnings are upgraded to errors, so you should do the casting, as the compiler indicates.
Is the following valid c11 code? I have checked the standard, and it seems unsupported, but I may be missing something. This example is a little contrived, but my actual situation involves like a thousand lines of code and wouldn't make much sense without all that context, and this example correctly isolates the principal I want to ask about. The point is that I use the function's own address by directly using its identifier.
typedef void(*ftype)(void*,void*);
void func(void* v, void* w)
{
if( func != (ftype)v ) ((ftype)v)( ((void**)w)[0], ((void**)w)[1]) );
}
So, the idea is to run the function pointed to by v for its side effects, with its input given by an array pointed to by w. However, it is desired to not run v if it happens to be a reference to the function 'func'.
EDIT: A comment answered the question: "A direct function call involves an implicit conversion ("decay") from the function name to a pointer to the function. Hence, every recursive function effectively takes its own address."
typedef void(*ftype)(void*,void*);
void func(void* v, void* w);
ftype myfunc = func; //here
Since we can take the address of functions that are 100% undefined in each translation unit, there's no reason that C should have a rule that disallows taking the address of a function that's partially defined. And when we check, there is indeed no such exception. Therefore, you can always take the address of a declared function, even inside the function.
I'm injecting a DLL into another process and want to call a function that is in that binary based on it's address (0x54315).
How can I actually declare a function, and then set it to this address?
#define FUNC 0x54315
void *myFuncPtr;
int main()
{
myFuncPtr = FUNC; // pretty sure this isn't how
myFuncPtr(); // call it?
}
The existing answers work, but you don't even need a variable for the function pointer. You can just do:
#define myfunc ((void (*)(void))0x54315)
and then call it as myfunc() just like you would an ordinary function. Note that you should change the type in the cast to match the actual argument and return types of the function.
You need to define myFuncPtr as a function pointer, a void* isn't callable.
Best to use a typedef for that:
typedef void (*funptr)(void);
funprt myFuncPtr;
(Assuming your function takes nothing and returns nothing.)
Then you'll get a warning on the assignment - use a type cast to "silence" it, since this is indeed what you need to do.
You're pretty much on your own with this though, if the signature doesn't match, the calling convention is wrong, or the address is wrong, the compiler cannot validate anything and you get to pick up the pieces.
Your code should work once the syntax is corrected to actually be a function pointer. I failed to read it properly for my first version of this answer. Sorry.
As stated by Mat, the proper syntax for a function pointer would be:
void (*myFuncPtr)(void) = (void (*)(void)) FUNC;
This is often simplified by using a typedef since the C function pointer syntax is somewhat convoluted.
Also, you're must be really sure the function to be called is at that same exact address every time your injected DLL runs. I'm not sure how you can be sure of that, though ...
Also, you would need to pay attention to the calling conventions and any arguments the function at FUNC might be expecting, since if you get that wrong you will likely end up with stack corruption.