Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Are there references in C?

Parent

Are there references in C?

+9
−0

When reading posts at programming sites such as this one, I frequently encounter people saying things like:

"There is no pass-by-reference in C, everything is passed by value."

People claiming such tend to be of the C++ programmer variety and are used to the C++ syntax distinction between pointers int* and references int&, which doesn't exist in C. And the argument usually goes:

void func (int* x);
...

int* p = &data;
func(p); // here the pointer p is passed by value

And sure, there is no denying that the pointer in this example is passed by value.

Questions: Are there references in C? Is it possible to pass variables by reference in C?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

1 comment thread

What's the point? (2 comments)
Post
+11
−0

C does have references, but it does not have pass by reference.

A reference is simply an expression that references an object (object here is meant in the general sense, not in the OO sense; for example, a variable is an object). In C, references are implemented using pointers.

However C does not have pass by reference. Note that pass by reference is not just the ability to pass references to functions (C certainly can do that), but refers to a mechanism by which the compiler turns an expression referring to an object (in C speak, an lvalue) used as argument to a function into a reference to that object named by that function's parameter.

C doesn't have that; if you want to pass a reference to an object you always have to be explicit about it, by passing a pointer (which then is passed by value) and dereferencing it in the called function.

C++ does have pass by reference via its reference types. Other languages allow pass by reference via special syntax (like var parameters in Pascal) or do it for all parameters (e.g. FORTRAN 77).

Note that pass by reference is mainly a syntactic thing (it makes a difference in language ability only in languages that don't allow passing references in any other way, like FORTRAN 77).

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

Then what about arrays? (8 comments)
Then what about arrays?
Lundin‭ wrote almost 3 years ago

"if you want to pass a reference to an object you always have to be explicit about it" How do you explain this then? void func (int arr[n]);

Lundin‭ wrote almost 3 years ago

Similarly, how can you explain passing a function to a function, is this pass by value: void func (void f(void)); Of course not.

__blackjack__‭ wrote over 2 years ago

Those are both function declarations, not calls. When you call those then you pass a pointer to the array in the first case and a pointer to a function in the second case. In neither case it is call by reference.

Lundin‭ wrote over 2 years ago

__blackjack__‭ No, in the first case you pass the array object and in the second case the function. As per various rules of parameter decay, the compiler will implicitly adjust them to pointers. Just as for example Java will implicitly adjust an object passed as parameter to a reference - same thing.

Lorenzo Donati‭ wrote over 1 year ago · edited over 1 year ago

Lundin‭ Sorry, I disagree. In the first case you specify an array, but that array is not actually passed to the function (i.e. the function doesn't get direct access to the object). Array decay makes that completely equivalent to directly pass a pointer, which is copied. The function always gets a copy of an object (in this case a pointer). If the array would be actually passed, you could use sizeof on the argument and get the size of the array, which you can't do since you get just a copy of a pointer. I concede that the syntax rules of C makes the distinction here murky, but the underlying mechanism is uniform: copy the argument (i.e. pass-by-value). The fact that the array decays into a pointer is something that happens before the argument is actually passed.

Lorenzo Donati‭ wrote over 1 year ago · edited over 1 year ago

Lundin‭ Moreover your example of a "function passed by reference" is not relevant, since functions in C are not objects (they are not first class values), so there is nothing to be passed except their pointers. That's true even in other contexts. Function identifiers represent pointers to the code of the function. Function pointers are also a different kind of beasts: you cannot modify a function using a pointer, they are intrinsically read only. So in a sense you could argue it is pass-by-reference, but actually it is only apparent, since the underlying mechanism is really pass-by-value (copy a pointer that happens to be a pointer to function), there is no special mechanism for functions.

Lundin‭ wrote over 1 year ago

Lorenzo Donati‭ A C++ reference does not pass the object to the function either. Array decay only makes arrays equivalent to pointers in the first dimension, int arr[n] decays to int*. But that is not true for int arr[x][y] which decays to int (*arr)[y], which is pretty much 100% equivalent to a C++ reference in every single aspect. C++ reference too are passed by value... unless the function is inlined behind the scenes. What it boils down to is how computers work, calling convention and ISA. And in a computer there is nothing called "pointer" or "reference", only addresses and direct vs indirect addressing. The terms "pointer" or "reference" otherwise have no universal or formal meaning outside a very specific programming language.

Lorenzo Donati‭ wrote over 1 year ago

Lundin‭ Mmm. I admit that your multidimensional array example had me stumped and I have to think about it. Moreover, I agree that the terms "pointers" and "references" are language-specific. What I argued about is the term "pass-by-reference", which is (on the contrary) quite standard (albeit the implementations of the mechanism may vary). There is some merit in distinguishing between the two cases: what you specify in a call can be accessed directly by the function (call-by-reference) or not (call-by-value). In a call-by-reference situation the parameter inside the function is an alias for the actual argument passed to the function (how it is implemented is irrelevant to the terminology, although using machine addresses is probably the most common case). You may argue that a C++ reference is a pointer in disguise that is automatically dereferenced, but that's an implementation detail and the net effect is the same (you don't get to see the copy even if it happens under the hood).