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
Notifications
Mark all as read
Q&A

Are there references in C?

+8
−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?

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

4 answers

+8
−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).

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Then what about arrays? (4 comments)
+6
−1

Yes there are references and pass-by-reference in C, though the language has no explicit syntax item called "reference" like C++. In a C context, it is irrelevant that C++ happens to have something called references, which are basically glorified, read-only pointers.

The general computer science term reference pre-dates C and C++ both. Therefore, saying "pass by reference" is perfectly acceptable in any computer science context. It is a broad and general term.

As explained in that Wikipedia link, it is analogous to indirect access, which is a term used in assembler on the low-level machine code layer. There, direct addressing means accessing a value directly from a given address, but indirect addressing means accessing it through a provided index register containing the address. These CPU core index registers are where C and C++ compilers prefer to store the higher level concepts of pointers and references. But there is no distinction between pointers and references in the machine code - it's all translated to raw addresses.


If we look at the formal definitions of terms in the current ISO 9899:2018 C standard, we find this at 6.2.5/20:

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”.

A pointer type is a so-called derived type, meaning that it is always based on one of the object types (like int).


Given these formal definitions, then we can look at the code example in the question:

void func (int* x);

  • The pointer type is int*, here represented by the variable x, and it is passed by value.
  • The referenced type is int and an object of that type, allocated elsewhere, is passed by reference.

int* p = &data;

  • p is a pointer type.
  • data is a complete object type, presumably of type int.

func(p);

  • p is passed by value.
  • data is passed by reference.
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+0
−0

This question most often comes up in relation to C++. That language has something that is called reference in the standard. They work like pointers, with a few differences.

  1. They have to be initialized, because (2)
  2. They cannot be reassigned. They will always point to the same object.
  3. They cannot point to null.
  4. They are always implicitly dereferenced. No dereferenciation is required or even allowed.

So C++ references are quite similar to const pointers, which should not be mixed up with pointer to const. A const pointer does not technically need to be initialized, but it's rather point(haha)less to not do it, because then they're completely useless. In C++, you will get a compiler error for both uninitialized references and const pointers.

The answer is yes or no, depending on how you want to interpret the phrase "pass by reference". It's both practical and common to talk about that in C, but it is also important to know the difference to "real" pass by reference. For instance, this code is guaranteed* to print 42 in C regardless of how foo() is defined, but that's not the case in C++.

int x = 42;
foo(x);
printf("%d\n", x);

* I'm not 100% sure that there isn't a way to provide a counterexample, but that would probably be some real fancy schmancy stuff.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+0
−4

As per ISO 9899:2018, 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”.

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Superfluous answer... (1 comment)

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!

Like what we're doing? Support us! Donate