[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

References in C

jacob navia

6/24/2011 8:42:00 AM

The lcc-win compiler is an experimental compiler to promote the
development of C as a language. Contrary to the main trends of language
design this days, lcc-win considers C not a dead language but a language
that can evolve and propose new features.

In this context, one of the extensions that lcc-win supports is
references, where the design is largely inspired from the C++ design.


What are references?

In fact, a reference is just a pointer. It is different from plain
pointers in two ways:

(1) It is always assigned to a concrete object when it is defined.
(2) Once defined, it will always point to that same object. It can't
be changed to point into another object.
(3) It is used with the '.' notation, as if it weren't a pointer.
(4) Instead of "*' the symbol "&" is used:
int i = 23;
int &IntReference = i;

As always in this proposals, the problems hide in the details. For
instance, several days ago someone complained that a reference to
void would not compile, but a pointer to void would. This prompted
me to correct a problem in my implementation: I should have forbidden to
build references to void!

The problem is when defining a reference but when you pass a reference
to a function:
int fn(void &ref);
In this case there is no initialization (that would explode immediately)
but just a definition without any initialization. The compiler must
check, then, that the reference is not to a void pointer.

Since the object pointed to by a reference can't change, many people
think that the value can't never change but that is wrong. Consider:

#include <stdio.h>
int main(void)
{
int i = 23;
int &pi = i;

i = 3;
printf("%d\n",pi);
}

The reference is initialized to an integer whose value is 23.
If the integer changes its value, the reference (like all other
pointers) changes its value also.

The advantages of using references are that they are never NULL,
and that they always point to the same object, two important
things less to test. The only (orthodox) way of declaring a non-NULL
pointer in an argument list is now:

int fn(int arg[static 1]);

This declares that the "arg" argument will have at least one integer
Few people know this, and it wasn't much explained when C99 introduced
it.

jacob
135 Answers

cr88192

6/24/2011 9:54:00 AM

0

On 6/24/2011 1:42 AM, jacob navia wrote:
> The lcc-win compiler is an experimental compiler to promote the
> development of C as a language. Contrary to the main trends of language
> design this days, lcc-win considers C not a dead language but a language
> that can evolve and propose new features.
>
> In this context, one of the extensions that lcc-win supports is
> references, where the design is largely inspired from the C++ design.
>

a partial risk though is that C + bunches-of-extensions is no longer C,
rather, another C derived language (in a similar manner to C++ or
Objective-C, which are also not strictly C).


>
> What are references?
>
> In fact, a reference is just a pointer. It is different from plain
> pointers in two ways:
>
> (1) It is always assigned to a concrete object when it is defined.
> (2) Once defined, it will always point to that same object. It can't
> be changed to point into another object.
> (3) It is used with the '.' notation, as if it weren't a pointer.
> (4) Instead of "*' the symbol "&" is used:
> int i = 23;
> int &IntReference = i;
>
> As always in this proposals, the problems hide in the details. For
> instance, several days ago someone complained that a reference to
> void would not compile, but a pointer to void would. This prompted
> me to correct a problem in my implementation: I should have forbidden to
> build references to void!
>
> The problem is when defining a reference but when you pass a reference
> to a function:
> int fn(void &ref);
> In this case there is no initialization (that would explode immediately)
> but just a definition without any initialization. The compiler must
> check, then, that the reference is not to a void pointer.
>
> Since the object pointed to by a reference can't change, many people
> think that the value can't never change but that is wrong. Consider:
>
> #include <stdio.h>
> int main(void)
> {
> int i = 23;
> int &pi = i;
>
> i = 3;
> printf("%d\n",pi);
> }
>
> The reference is initialized to an integer whose value is 23.
> If the integer changes its value, the reference (like all other
> pointers) changes its value also.
>
> The advantages of using references are that they are never NULL,
> and that they always point to the same object, two important
> things less to test. The only (orthodox) way of declaring a non-NULL
> pointer in an argument list is now:
>
> int fn(int arg[static 1]);
>
> This declares that the "arg" argument will have at least one integer
> Few people know this, and it wasn't much explained when C99 introduced
> it.
>

going OT:

interestingly, in my own current language (more closely related to
JavaScript and ActionScript), I ended up giving references a "look and
feel" more like that of C pointers.

basically, the caller needs to use "&" to pass an argument to a
reference, and by default (no '&' in the argument list) it would be
needed to use '*' to access/assign them. if '&' is given, it means to
insert an implicit '*' on access, and later could also insert basic
sanity checks (barf if the argument is not "sane" when calling the
function).

as-is, I figured doing calls like "foo(&x);" to be a reasonable
trade-off (it serves a similar role to 'ref' in C#).

note that, unlike C, these are not raw pointers, rather a
boxed-pointer-type (some languages use the term "locative" for these
instead of "pointer" or "reference").


Ian Collins

6/24/2011 10:10:00 AM

0

On 06/24/11 09:53 PM, BGB wrote:
> On 6/24/2011 1:42 AM, jacob navia wrote:
>> The lcc-win compiler is an experimental compiler to promote the
>> development of C as a language. Contrary to the main trends of language
>> design this days, lcc-win considers C not a dead language but a language
>> that can evolve and propose new features.
>>
>> In this context, one of the extensions that lcc-win supports is
>> references, where the design is largely inspired from the C++ design.
>>
>
> a partial risk though is that C + bunches-of-extensions is no longer C,
> rather, another C derived language (in a similar manner to C++ or
> Objective-C, which are also not strictly C).

C++--?

--
Ian Collins

Bartc

6/24/2011 10:15:00 AM

0

"jacob navia" <jacob@spamsink.net> wrote in message
news:iu1iku$4k9$1@speranza.aioe.org...

> #include <stdio.h>
> int main(void)
> {
> int i = 23;
> int &pi = i;
>
> i = 3;
> printf("%d\n",pi);
> }

This doesn't compile in my lcc-win32 unless I make i static ("addressable
object required" in the int &pi line).

Is this a restriction, or do I need an update?

--
Bartc

Shao Miller

6/24/2011 1:26:00 PM

0

On 6/24/2011 04:42, jacob navia wrote:
> The lcc-win compiler is an experimental compiler to promote the
> development of C as a language. Contrary to the main trends of language
> design this days, lcc-win considers C not a dead language but a language
> that can evolve and propose new features.
> ...
> In fact, a reference is just a pointer. It is different from plain pointers in two ways:
>
> (1) It is always assigned to a concrete object when it is defined.
> (2) Once defined, it will always point to that same object. It can't
> be changed to point into another object.
> (3) It is used with the '.' notation, as if it weren't a pointer.
> (4) Instead of "*' the symbol "&" is used:
> int i = 23;
> int &IntReference = i;

(I think you meant "four ways". You must have started with 2 and then
remembered 2 more. ;) )

So I'm guessing that if you have:

void foo(struct xxx & bar) { /* ... */ }

If you have an object with "allocated" storage duration, you'd do:

struct xxx * bar;
/* ...See below... */
foo(*bar_ptr);

in order for 'foo' to work with the pointed-to object, right?

But before you perform the call, you must:
- Allocate the object
- Check that the allocation succeeds

If you do these things before calling 'foo', then 'foo' needn't check
for a null pointer, right? For:

void foo(struct xxx * bar) { /* ... */ }

"static" and "automatic" objects can have their addresses passed with
'&', right?

So this seems to be along the lines of #1, above.

Then there's also:

void foo(struct xxx * const bar) { /* ... */ }

and:

int i;
int * const ip = &i;

which appear to be along the lines of #2, above.

Am I understanding these two points correctly?

Tom St Denis

6/24/2011 1:49:00 PM

0

On Jun 24, 4:42 am, jacob navia <ja...@spamsink.net> wrote:
> The lcc-win compiler is an experimental compiler to promote the
> development of C as a language. Contrary to the main trends of language
> design this days, lcc-win considers C not a dead language but a language
> that can evolve and propose new features.
>
> In this context, one of the extensions that lcc-win supports is
> references, where the design is largely inspired from the C++ design.
>
> What are references?
>
> In fact, a reference is just a pointer. It is different from plain
> pointers in two ways:
>
> (1) It is always assigned to a concrete object when it is defined.
> (2) Once defined, it will always point to that same object. It can't
>     be changed to point into another object.
> (3) It is used with the '.' notation, as if it weren't a pointer.
> (4) Instead of "*' the symbol "&" is used:
>      int i = 23;
>      int &IntReference = i;

Simipler...

int func(int *ledata)
{
#define reflefdata (*ledata)
int a;

a = (refledata *= 4);
return a;
}

There, no more lazies.

Also no language change required. You can do things like sizeof
refledata, you can read/assign it, even take the address of it.

Tom

David Resnick

6/24/2011 2:15:00 PM

0

On Jun 24, 9:48 am, Tom St Denis <t...@iahu.ca> wrote:
> Simipler...
>
> int func(int *ledata)
> {
> #define reflefdata (*ledata)
>    int a;
>
>    a = (refledata *= 4);
>    return a;
>
> }
>
> There, no more lazies.

While I'm not sold on having references in C (not clear the it is THAT
big a win), this macro crud isn't the same thing as having a ref.
Main virtue of references is self-documentation and automated function
argument semantics enforcement IMHO...

i.e. in C you might have:

/* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
int func(int *ledata)
{
if ( ledata == NULL )
{
/* do something drastic */
}
}

You can express all that extra material without the comments, checks,
whatever, with the one little '&' in the

int func( int &ledata )

Earth shattering? No, but it is sometimes nice.

-David

jacob navia

6/24/2011 2:59:00 PM

0

Le 24/06/11 16:14, David Resnick a écrit :

> While I'm not sold on having references in C (not clear the it is THAT
> big a win), this macro crud isn't the same thing as having a ref.
> Main virtue of references is self-documentation and automated function
> argument semantics enforcement IMHO...
>
> i.e. in C you might have:
>
> /* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
> int func(int *ledata)
> {
> if ( ledata == NULL )
> {
> /* do something drastic */
> }
> }
>
> You can express all that extra material without the comments, checks,
> whatever, with the one little '&' in the
>
> int func( int&ledata )
>
> Earth shattering? No, but it is sometimes nice.
>
> -David

Precisely. It is not the best thing since baked bread but it is an
improvement that implies a small change in the language.

jacob navia

6/24/2011 2:59:00 PM

0

Le 24/06/11 12:14, BartC a écrit :
> "jacob navia" <jacob@spamsink.net> wrote in message
> news:iu1iku$4k9$1@speranza.aioe.org...
>
>> #include <stdio.h>
>> int main(void)
>> {
>> int i = 23;
>> int &pi = i;
>>
>> i = 3;
>> printf("%d\n",pi);
>> }
>
> This doesn't compile in my lcc-win32 unless I make i static
> ("addressable object required" in the int &pi line).
>
> Is this a restriction, or do I need an update?
>

I think you need an update... I introduced this several years
ago... I just compiled that and it works without any problems.

Please do not use it with -ansic though.


Tom St Denis

6/24/2011 4:08:00 PM

0

On Jun 24, 10:58 am, jacob navia <ja...@spamsink.net> wrote:
> Le 24/06/11 16:14, David Resnick a écrit :
>
>
>
> > While I'm not sold on having references in C (not clear the it is THAT
> > big a win), this macro crud isn't the same thing as having a ref.
> > Main virtue of references is self-documentation and automated function
> > argument semantics enforcement IMHO...
>
> > i.e. in C you might have:
>
> > /* Note: ledata absolutely CAN NOT and MUST NOT be NULL here */
> > int func(int *ledata)
> > {
> >       if ( ledata == NULL )
> >       {
> >            /* do something drastic */
> >       }
> > }
>
> > You can express all that extra material without the comments, checks,
> > whatever, with the one little '&' in the
>
> > int func( int&ledata )
>
> > Earth shattering?  No, but it is sometimes nice.
>
> > -David
>
> Precisely. It is not the best thing since baked bread but it is an
> improvement that implies a small change in the language.

I can't see a reason to not have it, but just the same I can't say
that my programming career has been taking back by it. What I would
love is Turbo Pascals "with" stmt. e.g.

struct { int foo, bar, whatever; } baz;

with (baz) {
foo = 4;
bar = 3 * foo;
whatever = bar - 5;
}

Which makes all the elements of "baz" local scope. That would beat
crap like

baz.foo = 4;
baz.bar = 3 * baz.foo;
baz.whatever = baz.bar - 5;

Of course then you have

int foo;
with (baz) {
foo = 4; // which foo?
}

But that's something specifications are for...

Ike Naar

6/24/2011 4:09:00 PM

0

On 2011-06-24, Tom St Denis <tom@iahu.ca> wrote:
> Simipler...
>
> int func(int *ledata)
> {
> #define reflefdata (*ledata)

Error prone; see below.

> int a;
>
> a = (refledata *= 4);

See above.

> return a;
> }