I saw the link http://www.cs.uregina.ca/Links/class-info/cplusplus/Standards/Disk10/aliasing_c.html about aliasing in c. The program there is shown below.
/********************************
An example of aliasing in C.
Output:
3
3
********************************/
#include < stdio.h >
int main()
{
int G_Var = 2;
/* call SomeFunction with the Global Variable as a parameter */
SomeFunction(G_Var);
return 0;
}
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
{
int G_Var;
int InputVar;
/* Global Variable is set to new value */
G_Var = InputVar + 1;
/* Equivalent to G_Var = G_Var + 1 */
printf("%i\n", InputVar);
printf("%i\n", G_Var);
}
Is the code correct and is working according to what is commented in the code?
Whoever wrote the link was severely incompetent and shouldn't be teaching C. They should rather enlist in a beginner's class themselves.
int G_Var = 2; is not a global variable, it is a local one with automatic storage duration. Both the one in main() and the one inside the function.
The code posted is C++, not C. C does not have references.
The term alias/aliasing refers to when several pointers (or C++ references) may be assumed to point at the same memory location.
int InputVar; in the function conflicts with the parameter name so the code doesn't make any sense. In case there were no name conflict, the variable would be uninitialized and then used, which would be senseless.
Is the code correct and is working according to what is commented in the code?
Whoever wrote this example was so confused that it's really hard to be telling what they are trying to teach, or in which language for that matter. The code does not compile for multiple fundamental reasons. Just forget about this mess.
Four things to say:
C does not have C++-kind of aliases/references. It is a C++ feature only.
So,
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
is wrong.
G_Var is not a global variable. You declare it two times to be local to main and SomeFunction. If you want to declare G_Var as global variable it has to be declared once at global scope, not inside of a function, and only access it by its name, not declaring its type twice.
But beside that the use of global variables is deprecated. Rather use parameter passing.
SomeFunction() isn't declared before the call to it in main(). Usually this would give you a diagnostic as the compiler don't know what SomeFunction() is.
InputVar is used as reference parameter, but also declared twice in SomeFunction. Here is a conflict.
I guess you never compiled this code before asking, which is a fault. It would have answered many questions of yours including the main one.
"Is the illustration on Aliasing in C correct?"
"Is the code correct and is working according to what is commented in the code?"
No, it isn't. The whole code is defective.
It gives the impression that the authors didn't knew how to either write correct C nor C++ code.
I'm reading a book the c programming language authored by Brian W. Kernighan and Dennis M. Ritchie.
The book lists code below
void strcpy(char *s, char *t){
while((*s = *t) != '\0'){
s++;
t++;
}
}
and says:
Because arguments are passed by value, strcpy can use the parameters
s and t in any way it pleases
which I'm not agreed with. Why above arguments are passed by value?
According to another book C how to program:
In C, you use pointers and the indirection operator to simulate
call-by reference. When calling a function with arguments that should
be modified, the addresses of the arguments are passed.
In latter point of view, it's definitely call-by-reference.
Please tell me which way is correct and why, thanks!
btw, after assignment *s = *t, which one is compared with '\0'? *s or *t?
C passes arguments by value, always, meaning that the called function receives a local copy of whatever the caller refers to.
The called function can modify the received value, because it is a local copy, without affecting the original value. For example:
char *test(char *s) {
s++;
return s;
}
t = test("A");
it's legal and shows that the parameter s can be modified without affecting the caller (which passes a literal...).
But the strcpy() of you example does something different: it takes a pointer s, and modifies what s points to. Pointers are powerful, and they can be used to simulate "pass by reference" (a pointer is a reference).
after assignment *s = *t is held, which one is compared with '\0'? *s or *t?
The *s: in C, an assignment returns a value - and the value is the value of the assigned variable after the assignment is done. Writing:
if (i=3) ...
is the same as
i=3;
if (i) ...
If i was a pointer the syntax would be different but the mechanism is the same, the assignment would "use" the pointer and the value of the whole assignment is used as expression to be evaluated in the test.
Many people consider that idiom to be something that’s neither call-by-value or call-by-reference. For what it’s worth, Kernighan and Ritchie’s The C Programming Language does call arrays and pointers in C “references,” although it uses only the term call-by-value and not call-by-reference. That usage seems to have gone out of fashion once C++ added a different language feature called references.
A function that accepts a pointer and dereferences it will generally compile to the same machine code as a function in a language with call-by-reference. One difference that is not merely the absence of syntactic sugar: if the pointer argument itself is not const, it is possible to reassign a new value to it and make it reference something else, which “call-by-reference” semantics do not allow. In a language with call-by-reference, you could not write s++ or t++ to make the function arguments reference different objects! (C strings are stored in such a way that you can add an offset to the pointer to obtain a substring, whereas most langauges store the length of the string in the first few bytes of its memory.) However, you can mostly think of a reference T& in C++ as equivalent to passing a T *const that is guaranteed not to be NULL, and that has an invisible asterisk in front of its name.
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.
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 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.