Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What was the reasoning behind &'s syntax?

234 views
Skip to first unread message

Rick C. Hodgin

unread,
May 3, 2016, 10:09:35 AM5/3/16
to
Why does C++ not allow this syntax on line 3:

01: int x, y, z;
02:
03: some_function(&x, &y, &z);
04: // ...
05:
06: void some_function(int& x, int& y, int& z)
07: {
08: // ...
09: }

But instead, it requires this syntax on line 3:

01: int x, y, z;
02:
03: some_function(x, y, z);
04: // ...
05:
06: void some_function(int& x, int& y, int& z)
07: {
08: // ...
09: }

If the usages on line 3 and line 6 are far away, you can't know from
line 3's usage that they are passed by reference without then going to
visit the line 6 function. And even though most editors will provide
that ability readily, it still seems to be a shortcoming in the C++
syntax, and I'm curious if anyone knows the reasoning behind that
decision to hide all visible markup on the line 3 source line to
differentiate it from merely passed parameters?

Best regards,
Rick C. Hodgin

Jerry Stuckle

unread,
May 3, 2016, 10:14:36 AM5/3/16
to
Because some_function(int& x, int& y, int& z) takes ints as parameters,
and some_function(&x, &y, &x) is passing pointers to ints.

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Rick C. Hodgin

unread,
May 3, 2016, 10:15:16 AM5/3/16
to
They could've used this syntax, for example, to differentiate it from
the & address-of value:

01: int x, y, z;
02:
03: some_function(@x, @y, @z);
04: // ...
05:
06: void some_function(int& x, int& y, int& z)
07: {
08: // ...
09: }

It's just confusing on the line 3 reference because those values can
be updated, but there's no visible way to know it without going through
the manual investigation of inquiring of each parameter. I.e., it
seems to be a notable syntax shortcoming.

Scott Lurndal

unread,
May 3, 2016, 10:34:54 AM5/3/16
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

>If the usages on line 3 and line 6 are far away, you can't know from
>line 3's usage that they are passed by reference without then going to
>visit the line 6 function.

I've never cared much for C++ reference variable for this very
reason, myself.

Jerry Stuckle

unread,
May 3, 2016, 1:04:21 PM5/3/16
to
They *could* have done a lot of things. But your method violates the
concept of a reference - not having to use special syntax in the code to
pass or use the reference. The only way you can tell if you have a copy
or a reference is to look at the function declaration/definition.

I don't argue that '&' is overused, but that's what they chose.

Rick C. Hodgin

unread,
May 3, 2016, 1:26:33 PM5/3/16
to
On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
> They *could* have done a lot of things. But your method violates the
> concept of a reference - not having to use special syntax in the code to
> pass or use the reference.

I WANT to use special syntax to pass by reference. I want it to show up
in source code so I know it's a reference rather than a value pass.

Rick C. Hodgin

unread,
May 3, 2016, 1:28:52 PM5/3/16
to
To be clear:

Pass-by-reference has legitimate value on its merits. It's a desirable
asset to have in a programming language. It just needs some syntax
tweaking to be readily usable (as Scott indicated).

In my opinion, the value comes in its utility, not in its current syntax.

Chris Vine

unread,
May 3, 2016, 1:56:16 PM5/3/16
to
"I WANT".

Its original purpose was as I understand it to permit efficient operator
overloading with a natural syntax. A little googling would have led you
here: http://www.stroustrup.com/bs_faq2.html#pointers-and-references

If you want a special syntax, use pointers. They have been there since
the beginning.

Paavo Helde

unread,
May 3, 2016, 2:32:46 PM5/3/16
to
Most class type objects are passed by reference. What you actually want
to show up in the source is pass by non-const reference.

What you can do is something like:

#include <iostream>

template<typename T>
class byref {
public:
T& ref;
operator T& () {
return ref;
}
explicit byref(T& ref): ref(ref) {}
};

template<typename T>
byref<T> ref(T& x) {
return byref<T>(x);
}

void some_function( byref<int> x) {
++x;
}

int main() {

int y = 1;
some_function(ref(y));
std::cout << y << "\n";
}

A believe a semi-decent compiler should be able to optimize the
templates away so there would be no runtime penalties.

hth
Paavo


Melzzzzz

unread,
May 3, 2016, 2:36:40 PM5/3/16
to
On Tue, 3 May 2016 07:09:14 -0700 (PDT)
"Rick C. Hodgin" <rick.c...@gmail.com> wrote:

Operator overloading. Having c = a + b; is more convenient then
c = &a + &b;

Rick C. Hodgin

unread,
May 3, 2016, 2:45:07 PM5/3/16
to
My position is that references have utility in that you don't need to
check if they're NULL, but they still operate the same way as a pointer
under the hood, updating remote data. They also require less syntax on
use in the target function, which is desirable while still carrying out
remote data assignment. There's just no way to know if something is a
reference or not without additional interrogation of the source code.

Rick C. Hodgin

unread,
May 3, 2016, 2:50:23 PM5/3/16
to
What's wrong with:

void some_function(int& x) {
++x;
}

int main() {
int y = 1;
some_function(@y);
std::cout << y << "\n";
}

??

Why the need for the additional complexity?

-----
Anyway, my question was, "What was their thinking?" and I think I see
what it is now. I just happen to disagree with it.

Rick C. Hodgin

unread,
May 3, 2016, 2:54:26 PM5/3/16
to
On Tuesday, May 3, 2016 at 2:36:40 PM UTC-4, Melzzzzz wrote:
> Operator overloading. Having c = a + b; is more convenient then
> c = &a + &b;

I can see utility in that syntax, but while it is a pass-by-reference,
it's more pass-by-const-reference, where the values of a and b won't
be updated. So, why not have that syntax for values that are passed
by reference and not updated, but then allow or require the other
syntax when they could potentially be updated?

c = @a + @b;

In this case, a and/or b could possibly be updated. And in this case
they could not:

c = a + b;

Because in the case where there is no @ in use for a by-ref usage, it
is really just the equivalent of the thing being passed by pointer, but
without the extra syntax requirements on its use as the compiler does
all of that for you invisibly.

K. Frank

unread,
May 3, 2016, 2:57:14 PM5/3/16
to
Hi Rick!

On Tuesday, May 3, 2016 at 1:56:16 PM UTC-4, Chris Vine wrote:
To touch on what Paavo said, const references (different
from your example) don't really raise the same issue.

// could pass ints by value
// void some_function(int x, int y, int z);
// or we could pass ints by const reference
void some_function(const int& x, const int& y, const int& z);

// client code neither knows nor cares -- some_function
// promises not to modify x, y, or z through the reference
some_function(x, y, z);

Your point about non-const references is fully valid:

void some_function(int& x, int& y, int& z) { z++; }
some_function(x, y, z); // surprise! z gets modified

Should C++ permit this? Maybe not, but it's not high on my
list of things to worry about.

But Chris makes a good style suggestion: Pass by pointer
(not by non-const reference) if the function might modify
those arguments. (This is what I generally do. I either
"forbid" the use of null -- and other invalid -- pointers,
or test for them.)


Happy Hacking!


K. Frank

Rick C. Hodgin

unread,
May 3, 2016, 3:03:06 PM5/3/16
to
It's what I do too, but I'm thinking the extra syntax requirements and
dereferencing steps are a little obtuse and could be cleaned up by using
the const reference in the case of mere usage (for structs and objects
mostly, but theoretically for fundamental types as well), and for non-const
references, use something like the @x syntax which also maintains the
cleaner syntax on use, as well as the non-need to test if the passed ptr
is NULL before using it.

It just seems like there would be a win-win there if the @x syntax were
introduced, to indicate visually that it is a pass-by-ref, and that its
contents could be updated, while also affording the non-pointer usage,
which can make source code cleaner at times.

> Happy Hacking!
> K. Frank

:-)

Chris Vine

unread,
May 3, 2016, 3:06:07 PM5/3/16
to
On Tue, 3 May 2016 11:44:53 -0700 (PDT)
"Rick C. Hodgin" <rick.c...@gmail.com> wrote:
[snip]
> My position is that references have utility in that you don't need to
> check if they're NULL, but they still operate the same way as a
> pointer under the hood, updating remote data. They also require less
> syntax on use in the target function, which is desirable while still
> carrying out remote data assignment. There's just no way to know if
> something is a reference or not without additional interrogation of
> the source code.

You have a position. It's a trade off. You want someone summing two
complex numbers to write @a + @b, instead of a + b. I don't, nor
apparently did the language designers.

There may well be other languages which suit you better: perhaps one
which passes all objects by reference, so there is no need to look it
up. There are plenty which work that way (probably more do than don't).

Gareth Owen

unread,
May 3, 2016, 3:09:16 PM5/3/16
to
I think its a very good reason to use non-const references as function
arguments sparely, and only with a function name that implies what
mutations take place.

e.g.
increment(x); // no need to see the prototype void increment(int&);

void transpose(Matrix &);

is probably better than

Matrix transpose(const Matrix&);

if memory is tight relative to the size of your matrices.

I seem to recall Scott Meyers suggesting that if you're going to do a
memory allocation for a large object, you might as well get it done early:

Matrix transpose(Matrix);

const references are a different kettle of fish, because at the call
site you (usually) don't care if its pass-by-value or
pass-by-const-reference (or when you do care, you often want the const
reference version).

Gareth Owen

unread,
May 3, 2016, 3:12:07 PM5/3/16
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> Pass-by-reference has legitimate value on its merits. It's a desirable
> asset to have in a programming language.

How does your suggestion

some_function(@x, @y, @z);
void some_function(int& x, int& y, int& z);

differ from

some_function(&x, &y, &z);
void some_function(int* x, int* y, int* z)

?

Rick C. Hodgin

unread,
May 3, 2016, 3:17:02 PM5/3/16
to
In important ways related to use:

some_function(@x, @y, @z);

void some_function(int& x, int& y, int& z)
{
// Use immediately with cleaner syntax
other_thing(x + y + z);
}

Versus:

some_function(&x, &y, &z);

void some_function(int* x, int* y, int* z)
{
// Make sure pointers aren't NULL
if (x && y && z)
other_thing(*x + *y + *z);

Chris Vine

unread,
May 3, 2016, 3:19:00 PM5/3/16
to
His argument elsewhere in this thread is that references avoid needing
to check for NULL, so ought to exist but only with a pointer-like
syntax.

I think that is a weak advantage for the additional syntactic
complexity that he proposes. In any event, Stroustrup presumably did.

Gareth Owen

unread,
May 3, 2016, 3:28:52 PM5/3/16
to
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> writes:

> I think that is a weak advantage for the additional syntactic
> complexity that he proposes.

I think it's a good argument - at least for references vs. naked
pointers. Tony Hoare didn't call null references a "billion dollar
mistake" lightly.

But ... the present reference syntax prevents null references (except by
deliberately lying to the compiler) already.

I see a good case for insisting pass-by-non-const-reference have a
little syntactic twist. That really does aid understanding,
particularly if your function names don't help.

Matrix m = { ... };

// does this modify m in place? Better check the docs.
vector<double> lambda = eigensystem(m);

// Oh, I remember, m contains the eigenvectors when we're done
vector<double> lambda = eigensystem(@m);

> In any event, Stroustrup presumably did.

So it would seem.

Rick C. Hodgin

unread,
May 3, 2016, 3:30:45 PM5/3/16
to
On Tuesday, May 3, 2016 at 3:17:02 PM UTC-4, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 3:12:07 PM UTC-4, gwowen wrote:
> > "Rick C. Hodgin" <rick.c...@gmail.com> writes:
> >
> > > Pass-by-reference has legitimate value on its merits. It's a desirable
> > > asset to have in a programming language.
> >
> > How does your suggestion
> >
> > some_function(@x, @y, @z);
> > void some_function(int& x, int& y, int& z);
> >
> > differ from
> >
> > some_function(&x, &y, &z);
> > void some_function(int* x, int* y, int* z)
> >
> > ?
>
> In important ways related to use:

If the values were updated:

> some_function(@x, @y, @z);
>
> void some_function(int& x, int& y, int& z)
> {
> // Use immediately with cleaner syntax
> other_thing(x + y + z);
x = 12;
y = 13;
z = 14;
> }

If the values were not updated:

some_function(x, y, z);

void some_function(const int& x, const int& y, const int& z)
{
// Use immediately with cleaner syntax
other_thing(x + y + z);
}

In this case, the fact that there is no @ doesn't matter because they
aren't updated. Only in the case of the non-const reference which
could potentially result in a value change would the @ be required.

This has been an evolution in my thinking throughout this post, though
I do not see any reason why the @ couldn't always be used to signify
that it is a pass-by-ref usage, rather than something else.

> Versus:
>
> some_function(&x, &y, &z);
>
> void some_function(int* x, int* y, int* z)
> {
> // Make sure pointers aren't NULL
> if (x && y && z)
{
> other_thing(*x + *y + *z);
*x = 12;
*y = 13;
*z = 14;
}
> }

In additional usage as well.

Öö Tiib

unread,
May 3, 2016, 3:33:25 PM5/3/16
to
Error here: 'x' is passing to inbuilt operator++ just by value in your
theory so it should be '++@x;'.

> }
>
> int main() {
> int y = 1;
> some_function(@y);
> std::cout << y << "\n";
> }
>
> ??
>
> Why the need for the additional complexity?

Would it be simpler to write '++@x;' instead of '++x'? Also it would
lose all backward compatibility with C.

>
> -----
> Anyway, my question was, "What was their thinking?" and I think I see
> what it is now. I just happen to disagree with it.

In C++ we typically pass arguments by reference to const or by reference
or by r-value reference. Perhaps it would reduce the confusion if passing
by value had a special syntax but that is also missing because of backward
compatibility with C.

Gareth Owen

unread,
May 3, 2016, 3:38:03 PM5/3/16
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> In this case, the fact that there is no @ doesn't matter because they
> aren't updated. Only in the case of the non-const reference which
> could potentially result in a value change would the @ be required.

I think that's a really good idea -- but I think you'll struggle to get
it adopted formally.

> This has been an evolution ...

Must ... resist ... cheap ... intelligent ... design ... joke ... :)

Rick C. Hodgin

unread,
May 3, 2016, 3:40:34 PM5/3/16
to
I was not aware C compilers allowed pass-by-ref syntax without some unique
compiler extensions / allowances being used. I thought they were a new
creation provided for by C++.

Rick C. Hodgin

unread,
May 3, 2016, 3:43:41 PM5/3/16
to
On Tuesday, May 3, 2016 at 3:33:25 PM UTC-4, Öö Tiib wrote:
> On Tuesday, 3 May 2016 21:50:23 UTC+3, Rick C. Hodgin wrote:
> > What's wrong with:
> > void some_function(int& x) {
> > ++x;
>
> Error here: 'x' is passing to inbuilt operator++ just by value in your
> theory so it should be '++@x;'.

No. Usage within the function would be normal syntax. However, if you
wanted to pass it again by reference, then you could use @x. Otherwise
it would be driven by the called function.

Chris Vine

unread,
May 3, 2016, 3:44:04 PM5/3/16
to
On Tue, 03 May 2016 20:28:38 +0100
Gareth Owen <gwo...@gmail.com> wrote:
> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> writes:
>
> > I think that is a weak advantage for the additional syntactic
> > complexity that he proposes.
>
> I think it's a good argument - at least for references vs. naked
> pointers. Tony Hoare didn't call null references a "billion dollar
> mistake" lightly.
>
> But ... the present reference syntax prevents null references (except
> by deliberately lying to the compiler) already.
>
> I see a good case for insisting pass-by-non-const-reference have a
> little syntactic twist. That really does aid understanding,
> particularly if your function names don't help.

A little, but in an era of multiple processors not much. You may still
need to know whether an object is passed by reference to const or by
value for other reasons. If passed by reference to const, you know that
the receiving function will not mutate the object in the absence of an
obnoxious sleight of hand, but there is nothing to say another thread
with a non-const reference to the same object may not do so. So it
does not give an answer to such things as whether locking on reads is
required.

I don't think the gain is worth the additional syntax. Reasonable
people can disagree (you do). For sure though, the language
specification on this is not going to change.

Rick C. Hodgin

unread,
May 3, 2016, 3:48:00 PM5/3/16
to
On Tuesday, May 3, 2016 at 3:44:04 PM UTC-4, Chris Vine wrote:
> On Tue, 03 May 2016 20:28:38 +0100
> Gareth Owen <gwo...@gmail.com> wrote:
> > Chris Vine <chris@cvine--nospam--.freeserve.co.uk> writes:
> >
> > > I think that is a weak advantage for the additional syntactic
> > > complexity that he proposes.
> >
> > I think it's a good argument - at least for references vs. naked
> > pointers. Tony Hoare didn't call null references a "billion dollar
> > mistake" lightly.
> >
> > But ... the present reference syntax prevents null references (except
> > by deliberately lying to the compiler) already.
> >
> > I see a good case for insisting pass-by-non-const-reference have a
> > little syntactic twist. That really does aid understanding,
> > particularly if your function names don't help.
>
> A little, but in an era of multiple processors not much. You may still
> need to know whether an object is passed by reference to const or by
> value for other reasons. If passed by reference to const, you know that
> the receiving function will not mutate the object in the absence of an
> obnoxious sleight of hand, but there is nothing to say another thread
> with a non-const reference to the same object may not do so. So it
> does not give an answer to such things as whether locking on reads is
> required.

That's a systemic issue though, and not a language issue.

> I don't think the gain is worth the additional syntax. Reasonable
> people can disagree (you do). For sure though, the language
> specification on this is not going to change.

:-) I've found that to be the case reliably in the comp.std.c group
as well (with a proposal to remove the requirement of having forward
declarations, as I wanted the compiler to go ahead and ignore the
first pass errors, and continue on looking for the missing declaration
or definition for use, provided it exists _somewhere_ in the source
code, so as to greatly simplify header ordering, and to even potentially
remove the need for header files by allowing the compiler to pre-parse
the raw source files and extract out relevant header information and
maintain that data persistently between compiles, refreshing it as
needed with some type of MAKE-like change comparison feature which would
kick off the recompile).

Bo Persson

unread,
May 3, 2016, 3:50:07 PM5/3/16
to
And we still have the problem that with

int *x, *y, *z;

we call the function as

some_function(x, y, x);


How do we know what values might be modified?

Why is there no special syntax for this? :-)



Bo Persson



Rick C. Hodgin

unread,
May 3, 2016, 3:56:14 PM5/3/16
to
Well, I think when we use pointers we already expect them to be updated.
But you're right, that's not always the case.

You bring up an interesting point. There's no reason why the @ syntax
couldn't be used there to indicate that it is a non-const usage, and could,
therefore, be updated.

some_function(@x, y, @x);

We know in this case x's members could be updated, but y won't. The
compiler could enforce usage of @ in the case of non-const usages, and
allow non-@ usages in the case of const usages.

-----
It's an interesting idea, but perhaps there could be another syntax to
signify a non-const usage exists as I think that would be good information
to know visually, rather than via a quick research effort.

Good question. I'll have to give it some thought.

Scott Lurndal

unread,
May 3, 2016, 4:02:00 PM5/3/16
to
Paavo Helde <myfir...@osa.pri.ee> writes:
>On 3.05.2016 20:26, Rick C. Hodgin wrote:
>> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>>> They *could* have done a lot of things. But your method violates the
>>> concept of a reference - not having to use special syntax in the code to
>>> pass or use the reference.
>>
>> I WANT to use special syntax to pass by reference. I want it to show up
>> in source code so I know it's a reference rather than a value pass.
>
>Most class type objects are passed by reference. What you actually want
>to show up in the source is pass by non-const reference.

With your coding style, that may, perhaps, be true.

That's not universally true by any means.

Gareth Owen

unread,
May 3, 2016, 4:19:18 PM5/3/16
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> You bring up an interesting point. There's no reason why the @ syntax
> couldn't be used there to indicate that it is a non-const usage, and could,
> therefore, be updated.
>
> some_function(@x, y, @x);

Ah, but what if the arguments are reference-to-pointer?

void some_function(int*&,int*&,int*&);

Elephants ... all the way down.

Rick C. Hodgin

unread,
May 3, 2016, 4:22:59 PM5/3/16
to
The general idea would be to ultimately look at the left-most form.
If it's not preceded with "const" then you'd need the @. :-)

Or, the opposite could be true, such that if it is a const it needs
some specific syntax. Both of those could be based on compiler
settings.

My primary concerns right now are in the silent pass-by-ref usgages
in syntax. I think they could all use the @ prefix to indicate they
are in use. However, I would also support an extension which would
then enforce additional syntax for non-const (or const) references,
so they are visibly cued in source code.

Paavo Helde

unread,
May 3, 2016, 4:28:54 PM5/3/16
to
Anything not expressed in the language can be encoded in the Hungarian
notation ;-) So that's what I have occasionally used for non-const
references:

void some_function(const int& x, int& y_out, int& z_inout) {
y_out = x + 1;
z_inout++;
}

I agree this is a bit ugly, but better than pointers (in my eye).
Non-const references should be avoided in general anyway. What's wrong
with packing the data in a class and using member functions instead?

Cheers
Paavo










Rick C. Hodgin

unread,
May 3, 2016, 4:29:15 PM5/3/16
to
I would like to add one more thought to this ... I believe the future of
software development is moving toward the GUI, and because the cost of
machine resources is decreasing so rapidly, it is an absolute given that
the close and intimate nature of the editor+gui+compiler relationship will
be such that any decent EGC combination would be able to signal all of
this for your visually without requiring actual source code markup.

It is one of the avenues I am moving toward in my design. That being said,
I still believe there should be some cue in source code, be it artificially
injected by the EGC, or manually injected by the developer.

Rick C. Hodgin

unread,
May 3, 2016, 4:59:50 PM5/3/16
to
On Tuesday, May 3, 2016 at 3:56:14 PM UTC-4, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 3:50:07 PM UTC-4, Bo Persson wrote:
> > And we still have the problem that with
> > int *x, *y, *z;
> >
> > we call the function as
> > some_function(x, y, x);
> >
> > How do we know what values might be modified?
> > Why is there no special syntax for this? :-)
> > Bo Persson
>
> It's an interesting idea, but perhaps there could be another syntax to
> signify a non-const usage exists as I think that would be good information
> to know visually, rather than via a quick research effort.
>
> Good question. I'll have to give it some thought.

I like the idea of using @var for references. And I think there could
be designates for const or non-conts usage, which could signal the compiler
to generate warnings on improper use.

I think use of the ' symbol after the variable name, which would be kind
of like what we see in math with a, a', a'', etc.

We could also use the ! symbol after the variable name, which would be
an indicator that it is not being changed.

Example:

// Signal by-ref usage:
some_function(@x, @y, @z);

// Signal by-ref usage, with non-const on x using ':
some_function(@x', @y, @z);

// We could also explicitly signal by-ref const usage using !:
some_function(@x', @y!, @z!);

In this case, we know by visual inspection that x, y, and z are all
passed by reference. We know also that x is non-const and could be
updated. We know that y and z are const and won't be updated.

I'm also open to other syntax suggestions. I don't know where either
of those would interfere with anything, and if/where they would, a
simple whitespace would be enough to delineate.

Ian Collins

unread,
May 3, 2016, 6:20:25 PM5/3/16
to
On 05/04/16 08:59, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 3:56:14 PM UTC-4, Rick C. Hodgin wrote:
>> On Tuesday, May 3, 2016 at 3:50:07 PM UTC-4, Bo Persson wrote:
>>> And we still have the problem that with
>>> int *x, *y, *z;
>>>
>>> we call the function as
>>> some_function(x, y, x);
>>>
>>> How do we know what values might be modified?
>>> Why is there no special syntax for this? :-)
>>> Bo Persson
>>
>> It's an interesting idea, but perhaps there could be another syntax to
>> signify a non-const usage exists as I think that would be good information
>> to know visually, rather than via a quick research effort.
>>
>> Good question. I'll have to give it some thought.
>
> I like the idea of using @var for references. And I think there could
> be designates for const or non-conts usage, which could signal the compiler
> to generate warnings on improper use.

The compiler already will generate warnings on improper use.

Non-const reference parameters are comparatively rare in C++ code, most
reference parameters are const which are all be indistinguishable from
pass by value to the caller, so no special notation is needed or desirable.

As others have said, sensible function naming should be used along with
non-const reference parameters. If you really want to be explicit,
there already is a special syntax - pass by pointer!

--
Ian Collins

Öö Tiib

unread,
May 3, 2016, 6:49:14 PM5/3/16
to
On Tuesday, 3 May 2016 22:43:41 UTC+3, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 3:33:25 PM UTC-4, Öö Tiib wrote:
> > On Tuesday, 3 May 2016 21:50:23 UTC+3, Rick C. Hodgin wrote:
> > > What's wrong with:
> > > void some_function(int& x) {
> > > ++x;
> >
> > Error here: 'x' is passing to inbuilt operator++ just by value in your
> > theory so it should be '++@x;'.
>
> No. Usage within the function would be normal syntax.

Woosh. How can you call any functions or operators outside of a function?

> However, if you wanted to pass it again by reference, then you could
> use @x. Otherwise it would be driven by the called function.

[confused] That 'x' is passed by reference to operator++, operator++
modifies its value.

Geoff

unread,
May 3, 2016, 7:48:58 PM5/3/16
to
On Tue, 3 May 2016 10:26:22 -0700 (PDT), "Rick C. Hodgin"
<rick.c...@gmail.com> wrote:

>On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>> They *could* have done a lot of things. But your method violates the
>> concept of a reference - not having to use special syntax in the code to
>> pass or use the reference.
>
>I WANT to use special syntax to pass by reference. I want it to show up
>in source code so I know it's a reference rather than a value pass.
>

Then you should abandon C++ and take up C#. :-D

It has the ref keyword and function declarations, definitions and
calls must all have the ref keyword in order for it to compile. In the
IDE, Intellisense gives you the information as you type and shows you
the error list even before you compile.

C++ could have easily used a new keyword for this instead of
overloading & for it but apparently this was introduced before C++ was
'not C'.

Jorgen Grahn

unread,
May 3, 2016, 9:03:38 PM5/3/16
to
On Tue, 2016-05-03, Chris Vine wrote:
> On Tue, 03 May 2016 20:28:38 +0100
> Gareth Owen <gwo...@gmail.com> wrote:
>> Chris Vine <chris@cvine--nospam--.freeserve.co.uk> writes:
>>
>> > I think that is a weak advantage for the additional syntactic
>> > complexity that he proposes.
>>
>> I think it's a good argument - at least for references vs. naked
>> pointers. Tony Hoare didn't call null references a "billion dollar
>> mistake" lightly.
>>
>> But ... the present reference syntax prevents null references (except
>> by deliberately lying to the compiler) already.
>>
>> I see a good case for insisting pass-by-non-const-reference have a
>> little syntactic twist. That really does aid understanding,
>> particularly if your function names don't help.
>
> A little, but in an era of multiple processors not much.

Nitpick: having multiple processors doesn't mean you /have/ to use
threads, or use threads in such a way that you can have data races
anywhere in the code.

[snip]

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jerry Stuckle

unread,
May 3, 2016, 9:10:00 PM5/3/16
to
On 5/3/2016 1:26 PM, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>> They *could* have done a lot of things. But your method violates the
>> concept of a reference - not having to use special syntax in the code to
>> pass or use the reference.
>
> I WANT to use special syntax to pass by reference. I want it to show up
> in source code so I know it's a reference rather than a value pass.
>
> Best regards,
> Rick C. Hodgin
>

That's not how references work, Rick. The whole purpose is to *make them
transparent*.

If you want to use "special syntax", use pointers.

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Rick C. Hodgin

unread,
May 3, 2016, 10:17:16 PM5/3/16
to
The idea with the @var, and @var', and @var!, is to not have to use
keywords. It's the same idea as not having to write variables which
use name tags, like for x using x_in, x_out, or x_inout. I like x,
and I like @x to indicate visually that it's a reference. And I think
some kind of visual tags like @x' and @x! could be useful as well.
They could even be hidden in source code by the EGC, giving it a
colorization (rather than a mechanical character) syntax.

In any event ... my position's clear. I don't expect C++ to change,
but that's really not my goal. I was just curious why the C++ author
and ongoing maintainers have created and kept references as they have.

Öö Tiib

unread,
May 3, 2016, 10:19:21 PM5/3/16
to
You misread. I wrote that passing by copying the value would need special
syntax since passing by reference is more common than passing by value
in C++.

Rick C. Hodgin

unread,
May 3, 2016, 10:22:00 PM5/3/16
to
On Tuesday, May 3, 2016 at 9:10:00 PM UTC-4, Jerry Stuckle wrote:
> On 5/3/2016 1:26 PM, Rick C. Hodgin wrote:
> > On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
> >> They *could* have done a lot of things. But your method violates the
> >> concept of a reference - not having to use special syntax in the code to
> >> pass or use the reference.
> >
> > I WANT to use special syntax to pass by reference. I want it to show up
> > in source code so I know it's a reference rather than a value pass.
>
> That's not how references work, Rick. The whole purpose is to *make them
> transparent*.

Your posts are often difficult for me, Jerry, because you seem to only be
able to relate to the way things are, rather than to step outside of the
box a little and understand why someone would mention something like this.

I mention it because this...:

int x, y, z;
// x,y,z are populated
some_function(x, y, z);

...doesn't convey enough about the operation to know how x, y, and z are
used. They could be updated, or not. It's a lacking feature in C++, and
while I recognize the way the syntax works today, I think that decision
was wrong, and that it should possibly have an option to allow it to not
have something like the @x syntax, but I think by default the visual cue
should be included and available.

> If you want to use "special syntax", use pointers.

I want to use special syntax on the passing of parameters, but not on
every subsequent use (dereferencing, using -> instead of . and so on).

Pointers also convey baggage that values passed by reference don't,
such as the need to check for NULL values, which slows down processing,
and is redundant when using references.

There are reasons to use by-reference values. And for those reasons I
want to use them. I just want my source code to indicate to me when I
use them that I'm actually using them.

Rick C. Hodgin

unread,
May 3, 2016, 10:27:08 PM5/3/16
to
I did misread. My apologies.

I think all types should require no special syntax when passed by value,
but that all forms passed by pointer or reference should require additional
visual syntax so you know it from the place they're used as call parameters.

I am also thinking more and more as I get older that pointers and values
passed by-ref should be a lot more interchangeable than they are because
under the hood, fundamentally, they are the exact same operation, it's just
that by-ref values have several advantages, hence their wider use.

Jerry Stuckle

unread,
May 3, 2016, 11:02:33 PM5/3/16
to
On 5/3/2016 10:21 PM, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 9:10:00 PM UTC-4, Jerry Stuckle wrote:
>> On 5/3/2016 1:26 PM, Rick C. Hodgin wrote:
>>> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>>>> They *could* have done a lot of things. But your method violates the
>>>> concept of a reference - not having to use special syntax in the code to
>>>> pass or use the reference.
>>>
>>> I WANT to use special syntax to pass by reference. I want it to show up
>>> in source code so I know it's a reference rather than a value pass.
>>
>> That's not how references work, Rick. The whole purpose is to *make them
>> transparent*.
>
> Your posts are often difficult for me, Jerry, because you seem to only be
> able to relate to the way things are, rather than to step outside of the
> box a little and understand why someone would mention something like this.
>

I relate to the way things are because THAT'S THE WAY THINGS ARE. If
you don't like it - either suggest a change or use another language. In
this case, the change would not be accepted because it would break most
of the C++ programs in existence.

> I mention it because this...:
>
> int x, y, z;
> // x,y,z are populated
> some_function(x, y, z);
>
> ...doesn't convey enough about the operation to know how x, y, and z are
> used. They could be updated, or not. It's a lacking feature in C++, and
> while I recognize the way the syntax works today, I think that decision
> was wrong, and that it should possibly have an option to allow it to not
> have something like the @x syntax, but I think by default the visual cue
> should be included and available.
>

If they aren't going to be updated, then use const, i.e.

void some_function(const int x, int y, const int z);

In this case, x and z would not be updated, but y may be.

>> If you want to use "special syntax", use pointers.
>
> I want to use special syntax on the passing of parameters, but not on
> every subsequent use (dereferencing, using -> instead of . and so on).
>

You have a choice - use it all the time, not none of the time. You
can't pick and choose when you might want to use it.

> Pointers also convey baggage that values passed by reference don't,
> such as the need to check for NULL values, which slows down processing,
> and is redundant when using references.
>

Actually, not true. It is possible to pass a reference to NULL -
although you have to work at it.

> There are reasons to use by-reference values. And for those reasons I
> want to use them. I just want my source code to indicate to me when I
> use them that I'm actually using them.
>
> Best regards,
> Rick C. Hodgin
>

You can use them all of the time, or none of the time. But the function
itself can't accept a reference sometimes and a copy other times - just
like it can't accept a pointer sometimes, and a copy other times.

Use references all of the time, or copies all of the time when calling a
function. You can't do both.

Rick C. Hodgin

unread,
May 4, 2016, 12:15:21 AM5/4/16
to
On Tuesday, May 3, 2016 at 11:02:33 PM UTC-4, Jerry Stuckle wrote:
> On 5/3/2016 10:21 PM, Rick C. Hodgin wrote:
> > On Tuesday, May 3, 2016 at 9:10:00 PM UTC-4, Jerry Stuckle wrote:
> >> On 5/3/2016 1:26 PM, Rick C. Hodgin wrote:
> >>> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
> >>>> They *could* have done a lot of things. But your method violates the
> >>>> concept of a reference - not having to use special syntax in the code to
> >>>> pass or use the reference.
> >>>
> >>> I WANT to use special syntax to pass by reference. I want it to show up
> >>> in source code so I know it's a reference rather than a value pass.
> >>
> >> That's not how references work, Rick. The whole purpose is to *make them
> >> transparent*.
> >
> > Your posts are often difficult for me, Jerry, because you seem to only be
> > able to relate to the way things are, rather than to step outside of the
> > box a little and understand why someone would mention something like this.
> >
>
> I relate to the way things are because THAT'S THE WAY THINGS ARE. If
> you don't like it - either suggest a change or use another language.

The bulk of my reason for posting today was to propose alternatives, which
I have done. And as I've indicated in this thread, I have witnessed the
difficulty in getting anything new added to the C or C++ standard. I
don't expect anything to change, but my goals here aren't particularly
for C++ to change, but to learn of the fundamental reasons why that which
is in existence is, in fact, in existence.

My goals are CAlive... and I am focused on addressing this issue there.

> In
> this case, the change would not be accepted because it would break most
> of the C++ programs in existence.

It would break no C++ programs in existence because the feature would be
a new feature that would have to be enabled to be enforced. All legacy
code would work without the new syntax constraint, unless that constraint
were enabled in the compiler. Only then would it potentially break old
code. But, like renaming a global variable temporarily to find all of
its usages in a program by looking at the compiler errors, the source
code that was broken by the new syntax requirement would be easily
found, and resolved.

> > I mention it because this...:
> >
> > int x, y, z;
> > // x,y,z are populated
> > some_function(x, y, z);
> >
> > ...doesn't convey enough about the operation to know how x, y, and z are
> > used. They could be updated, or not. It's a lacking feature in C++, and
> > while I recognize the way the syntax works today, I think that decision
> > was wrong, and that it should possibly have an option to allow it to not
> > have something like the @x syntax, but I think by default the visual cue
> > should be included and available.
> >
>
> If they aren't going to be updated, then use const, i.e.
> void some_function(const int x, int y, const int z);
>
> In this case, x and z would not be updated, but y may be.

And we're again back to square one, that you don't know in the source
code whether or not things are being passed are by value, or by reference,
without the syntax markup.

By requiring the @x syntax for by reference values, and the x' for non-
const values, and x! for const values, it would resolve that issue. I'm
still not convinced of the x' and x! syntax, though they are growing on
me.

> >> If you want to use "special syntax", use pointers.
> >
> > I want to use special syntax on the passing of parameters, but not on
> > every subsequent use (dereferencing, using -> instead of . and so on).
>
> You have a choice - use it all the time, not none of the time. You
> can't pick and choose when you might want to use it.

The only place they need to be used are when being passed to something
that can change their value. When they're used within the function,
they are simply whatever type they are, even if they're by-reference
types to some remote data.

> > Pointers also convey baggage that values passed by reference don't,
> > such as the need to check for NULL values, which slows down processing,
> > and is redundant when using references.
>
> Actually, not true. It is possible to pass a reference to NULL -
> although you have to work at it.

I know of know way apart from doing something underhanded, such as using
a union with overloaded function calls, or calling a function with a
different function declaration which does not match the definition.

Internally, the source code generated for both of these is identical.
The pointers to main's x,y,z are pushed onto the stack, and their
values are updated through the pointer using identical assembly code:

void populate1(int& x, int& y, int& z)
{
x = 12; y = 13; z = 14;
}

void populate2(int* x, int* y, int* z)
{
*x = 22; *y = 23; *z = 24;
}

int main(int argc, char* argv[])
{
int x,y,z;

populate1(x,y,z);
populate2(&x, &y, &z);

return(0);
}

The compiler hides the relaxed syntax requirements on by-ref values for
you, but they are still internally identical to pointers.

This is why they're so desirable. It is greatly simplified syntax in
many cases, and it removes the NULL check requirement. The only issue
that is an issue is that you don't know in source code if things are
being passed by value or reference by mere inspection. It's my only
point in this thread.

> > There are reasons to use by-reference values. And for those reasons I
> > want to use them. I just want my source code to indicate to me when I
> > use them that I'm actually using them.
>
> You can use them all of the time, or none of the time. But the function
> itself can't accept a reference sometimes and a copy other times - just
> like it can't accept a pointer sometimes, and a copy other times.

FWIW, nobody's asking it to accept something one way part of the time, or
not another time. It will always be what it is. My point is that whenever
something is passed by reference, it should include the additional syntax.
It should not be required in other places.

> Use references all of the time, or copies all of the time when calling a
> function. You can't do both.

You've misunderstood somewhere, Jerry.

Christian Gollwitzer

unread,
May 4, 2016, 12:58:46 AM5/4/16
to
Am 04.05.16 um 04:21 schrieb Rick C. Hodgin:
> I want to use special syntax on the passing of parameters, but not on
> every subsequent use (dereferencing, using -> instead of . and so on).

You can use a reference variable:

void inc(int *x_) {
int & x = *x_
x++;
}

int y=2;
inc(&y);

> Pointers also convey baggage that values passed by reference don't,
> such as the need to check for NULL values, which slows down processing,
> and is redundant when using references.

Yes and no. Pointers can be null, but only if somebody passes in null
explicitly. If the function is used in the way shown above, they can't
be null. Many APIs segfault when you pass in NULL pointers. What else
should happen? Throw an exception? That will always be runtime overhead.
In cases where it can't be, the compiler can optimize it away. In cases
where it is not clear, a reference does not help. Consider

void dec (int &var) { --var; }

void buggy (SomeClass *c) {
dec(c->member);
}

buggy(nullptr);

Where is the bug? It crashes inside of "dec", because there the memory
near zero is written. But there is a reference which "can't be zero". Do
you blame "buggy" for not checking the pointer, that it might be zero?
Or is it the call? Most C-style APIs, which pass pointers to structs
around a lot in this way, blame the caller. Because the typical bug
arises from passing in a dangling pointer, such as from a deleted "Object".



Christian

Paavo Helde

unread,
May 4, 2016, 1:39:06 AM5/4/16
to
On 4.05.2016 7:15, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 11:02:33 PM UTC-4, Jerry Stuckle wrote:
[...]

> By requiring the @x syntax for by reference values, and the x' for non-
> const values, and x! for const values, it would resolve that issue. I'm
> still not convinced of the x' and x! syntax, though they are growing on
> me.

The @x! syntax is starting to remind Perl :-(

I believe part of the motivation behind reference syntax was to get rid
of the special syntax (*x, &x) so that the source code looked cleaner.

>>>> If you want to use "special syntax", use pointers.
>>>
>>> I want to use special syntax on the passing of parameters, but not on
>>> every subsequent use (dereferencing, using -> instead of . and so on).
>>
>> You have a choice - use it all the time, not none of the time. You
>> can't pick and choose when you might want to use it.
>
> The only place they need to be used are when being passed to something
> that can change their value.

This basically means non-const references only. If an object is modified
via a const reference (updating a mutable cache variable or locking a
mutex, etc), then the caller should not care.

>>> Pointers also convey baggage that values passed by reference don't,
>>> such as the need to check for NULL values, which slows down processing,
>>> and is redundant when using references.
>>
>> Actually, not true. It is possible to pass a reference to NULL -
>> although you have to work at it.

It is possible, bot not legal. So any time you see a "NULL reference" it
is clear that this is a bug which must be fixed ASAP, and the fix does
*not* involve adding a "NULL reference check" inside the function.

>
> This is why they're so desirable. It is greatly simplified syntax in
> many cases, and it removes the NULL check requirement. The only issue
> that is an issue is that you don't know in source code if things are
> being passed by value or reference by mere inspection. It's my only
> point in this thread.

Well, that's the point. In my code, I do not want to distinguish passing
an object via value or by const reference, because for the caller these
are semantically the same, and I do not want to add meaningless noise at
the call site. If I need an explicit copy for thread-pass or whatever, I
make an explicit copy, no point to hide it in the parameter passing
mechanisms. But this is just our coding style and conventions, I
understand YMMV.

For non-const references I agree that having it highlighted in the
calling code might be useful. Alas, this cannot be enforced because this
would break zillions lines of existing C++ code. For non-enforced
syntax: maybe it would be a solution for you to just create a tool or an
IDE extension which goes through the selected source files and adds *&
in front of each argument passed via a (non-const) reference?

Cheers
Paavo

Robert Wessel

unread,
May 4, 2016, 3:45:36 AM5/4/16
to
On Tue, 3 May 2016 12:16:49 -0700 (PDT), "Rick C. Hodgin"
<rick.c...@gmail.com> wrote:

>On Tuesday, May 3, 2016 at 3:12:07 PM UTC-4, gwowen wrote:
>> "Rick C. Hodgin" <rick.c...@gmail.com> writes:
>>
>> > Pass-by-reference has legitimate value on its merits. It's a desirable
>> > asset to have in a programming language.
>>
>> How does your suggestion
>>
>> some_function(@x, @y, @z);
>> void some_function(int& x, int& y, int& z);
>>
>> differ from
>>
>> some_function(&x, &y, &z);
>> void some_function(int* x, int* y, int* z)
>>
>> ?
>
>In important ways related to use:
>
> some_function(@x, @y, @z);
>
> void some_function(int& x, int& y, int& z)
> {
> // Use immediately with cleaner syntax
> other_thing(x + y + z);
> }
>
>Versus:
>
> some_function(&x, &y, &z);
>
> void some_function(int* x, int* y, int* z)
> {
> // Make sure pointers aren't NULL
> if (x && y && z)
> other_thing(*x + *y + *z);
> }
>


That's absurd. That references cannot be null are a minor feature of
references. Heck it's barely a feature - it's a side effect of how
references work. The entire point of references is the syntactical
ability to *not* make references explicit in the call. Now if you
don't like that feature, just don't use it.

If you just wanted non-null references, why not introduce an attribute
on pointer parameters in the function. Something like:

void f(notnull int *x)

Just like "restrict".

David Brown

unread,
May 4, 2016, 4:32:13 AM5/4/16
to
On 03/05/16 20:50, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 2:32:46 PM UTC-4, Paavo Helde wrote:
>> On 3.05.2016 20:26, Rick C. Hodgin wrote:
>>> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>>>> They *could* have done a lot of things. But your method violates the
>>>> concept of a reference - not having to use special syntax in the code to
>>>> pass or use the reference.
>>>
>>> I WANT to use special syntax to pass by reference. I want it to show up
>>> in source code so I know it's a reference rather than a value pass.
>>
>> Most class type objects are passed by reference. What you actually want
>> to show up in the source is pass by non-const reference.
>>
>> What you can do is something like:
>>
>> #include <iostream>
>>
>> template<typename T>
>> class byref {
>> public:
>> T& ref;
>> operator T& () {
>> return ref;
>> }
>> explicit byref(T& ref): ref(ref) {}
>> };
>>
>> template<typename T>
>> byref<T> ref(T& x) {
>> return byref<T>(x);
>> }
>>
>> void some_function( byref<int> x) {
>> ++x;
>> }
>>
>> int main() {
>>
>> int y = 1;
>> some_function(ref(y));
>> std::cout << y << "\n";
>> }
>>
>> A believe a semi-decent compiler should be able to optimize the
>> templates away so there would be no runtime penalties.
>
> What's wrong with:
>
> void some_function(int& x) {
> ++x;
> }
>
> int main() {
> int y = 1;
> some_function(@y);
> std::cout << y << "\n";
> }
>
> ??
>
> Why the need for the additional complexity?
>

The key point is that this solution can be used /today/, using standard
C++ compilers. Using an @ sign requires a new language, new compiler,
and a good deal of thought to be sure that it is consistent (as shown by
the issues around "++x" or "++@x" - after all, when overloaded, "++" is
a function that takes a non-const reference).

Obviously for your own language, you can use the syntax you want. But
this template idea will work for all C++ programmers. It is not a bad
idea - I agree with your principle argument that passing data by
non-const reference should be clearly indicated in some way (though I
want const reference passing to look exactly like value passing).


Ben Bacarisse

unread,
May 4, 2016, 6:33:53 AM5/4/16
to
David Brown <david...@hesbynett.no> writes:
<snip>

> The key point is that this solution can be used /today/, using standard
> C++ compilers. Using an @ sign requires a new language, new compiler,
> and a good deal of thought to be sure that it is consistent

You could use *& in place of @. This would enable the idea to be
tested: add an option to gcc that will warn when an object is referenced
via a non-const reference parameter but where the warning is suppressed
if the call uses *&. If it gets wide-spread use, it could be considered
for a future C++. It would not be unreasonable to keep *& as the
required way to signal "yes, I know this is a non-const reference
argument".

<snip>
--
Ben.

Rick C. Hodgin

unread,
May 4, 2016, 8:28:09 AM5/4/16
to
When you say "absurd," do you mean off-the-charts ludicrous? Or is it
merely somewhat obtuse? :-)

> The entire point of references is the syntactical
> ability to *not* make references explicit in the call.

I did mention that ability.

> Now if you
> don't like that feature, just don't use it.
>
> If you just wanted non-null references, why not introduce an attribute
> on pointer parameters in the function. Something like:
>
> void f(notnull int *x)
>
> Just like "restrict".

It's verbose. If x' would indicate change, and x! would indicate no
change, and @x indicates by-reference, and &x indicates pointer, then
it would be possible to convey typing using:

void some_function(int x, int y', int z!, int @a, int @b', int @c!);
// x = normal value/object with full range of abilities
// y = an out parameter (changed or possibly changed)
// z = an in parameter (unchanged)
// a = a reference with full range of abilities
// b = an out reference (changed or possibly changed)
// c = an in parameter (unchanged)

It would remove the extra verbosity of typing, while conveying a syntax
that can be used in function declaration / definition, as well as in
general syntax if desired, and I would argue that it should be used in
all cases of passing as a parameter.

We'll see though. I'll give it some more thought.

Rick C. Hodgin

unread,
May 4, 2016, 8:34:34 AM5/4/16
to
On Wednesday, May 4, 2016 at 12:58:46 AM UTC-4, Christian Gollwitzer wrote:
> Am 04.05.16 um 04:21 schrieb Rick C. Hodgin:
> > I want to use special syntax on the passing of parameters, but not on
> > every subsequent use (dereferencing, using -> instead of . and so on).
>
> You can use a reference variable:
>
> void inc(int *x_) {
> int & x = *x_
> x++;
> }
>
> int y=2;
> inc(&y);

Makes sense. It never would've occurred to me to do that. By using
pointers, it still requires checking for NULL though.

> > Pointers also convey baggage that values passed by reference don't,
> > such as the need to check for NULL values, which slows down processing,
> > and is redundant when using references.
>
> Yes and no. Pointers can be null, but only if somebody passes in null
> explicitly. If the function is used in the way shown above, they can't
> be null. Many APIs segfault when you pass in NULL pointers. What else
> should happen? Throw an exception? That will always be runtime overhead.
> In cases where it can't be, the compiler can optimize it away. In cases
> where it is not clear, a reference does not help. Consider
>
> void dec (int &var) { --var; }
>
> void buggy (SomeClass *c) {
> dec(c->member);
> }
>
> buggy(nullptr);
>
> Where is the bug? It crashes inside of "dec", because there the memory
> near zero is written. But there is a reference which "can't be zero". Do
> you blame "buggy" for not checking the pointer, that it might be zero?
> Or is it the call? Most C-style APIs, which pass pointers to structs
> around a lot in this way, blame the caller. Because the typical bug
> arises from passing in a dangling pointer, such as from a deleted "Object".

To answer your question:

The bug exists on the dec(c->member); line, or more generally in the
buggy() function. NULL values cannot be passed as reference legally,
so there needed to be checking done since the source value is a pointer.

BTW, in writing this response, it occurred to me that a buggy was a
most desirable and essential thing to have ... before the computer age.
But since the computer age, not so much, though perhaps for other
reasons. :-)

Rick C. Hodgin

unread,
May 4, 2016, 8:37:39 AM5/4/16
to
FWIW, I am amazed sometimes how people would look at a solution like that
and say that it's better for general developers than introducing a new
feature into the language which simplifies it greatly, such as the @ sign.

In any event, as with changes to C, changes to C++ are not my goal. There
is no fruit borne in those efforts, so I leave them be. My efforts in
asking questions and positing alternatives are for CAlive, not C, or C++.

David Brown

unread,
May 4, 2016, 8:50:21 AM5/4/16
to
Again, the key point here is that this solution is available here and
now, using existing tools. Putting something into your CAlive language
may be a fine solution for /you/, but for everyone else, this template
solution is infinitely better than "@" because it works /now/. It is
conceivable that your @ idea could be so popular that it might be
implemented in real-world C++ compilers, or future C++ standards - but
at best, that would be many years down the line.

And this template solution is not as bad as you seem to think, nor is
your @ solution as good. Obviously a lot comes down to opinion and
preference, but certainly I would say simple and clear text names like
"ref" and "byref" have a lot of advantages over another obtuse symbol
such as @. I don't think C++ needs more symbols. (The template
definition is of course a one-off. You would just put it in a header
somewhere, and forget about the implementation details.)

> In any event, as with changes to C, changes to C++ are not my goal. There
> is no fruit borne in those efforts, so I leave them be. My efforts in
> asking questions and positing alternatives are for CAlive, not C, or C++.
>

That's fine. But it is also nice when it touches on something directly
relevant to C and/or C++. In this case, you have a strong point that a
number of people agree with at least partially, and it is good to see
that there is a workable solution in existing languages. It is also
fine if you want to solve the problem in a somewhat different matter in
your own language.

And it's fine that /your/ main concern here is CAlive - but you should
not be surprised to see that most people's main concern in this
newsgroup is C++.



Rick C. Hodgin

unread,
May 4, 2016, 9:00:15 AM5/4/16
to
Again, my amazement comes from the fact that people would think that
this alternative would be desirable. But, generally speaking it is
how I feel about most C++ code I come across. It may be extensible
and reusable in various places, but it's not worth it. I'd rather
create a GUI editor extension language that would allow me to create
the template there, and have it pop in a few variables, and actually
generate source code for me, even if it contained some markup to allow
future edits to the template which, when changed, automatically went
into the source code and refactored those things which were from that
template.

> And this template solution is not as bad as you seem to think, nor is
> your @ solution as good. Obviously a lot comes down to opinion and
> preference, but certainly I would say simple and clear text names like
> "ref" and "byref" have a lot of advantages over another obtuse symbol
> such as @. I don't think C++ needs more symbols. (The template
> definition is of course a one-off. You would just put it in a header
> somewhere, and forget about the implementation details.)

I could be wrong in all my ideas. We'll see what the future holds when
CAlive is completed (James 4:15).

> > In any event, as with changes to C, changes to C++ are not my goal. There
> > is no fruit borne in those efforts, so I leave them be. My efforts in
> > asking questions and positing alternatives are for CAlive, not C, or C++.
>
> That's fine. But it is also nice when it touches on something directly
> relevant to C and/or C++. In this case, you have a strong point that a
> number of people agree with at least partially, and it is good to see
> that there is a workable solution in existing languages. It is also
> fine if you want to solve the problem in a somewhat different matter in
> your own language.
>
> And it's fine that /your/ main concern here is CAlive - but you should
> not be surprised to see that most people's main concern in this
> newsgroup is C++.

I am only surprised by the number of people who are willing to seek a
possible alternative, and then run with it, rather than trying to make
it simpler.

Writing a C++ compiler is difficult and it takes a lot of work. But that
large workload is nothing compared to the amount of work the millions of
developers world-wide go through on their various projects each day.

Because there is such a large base of developers who would benefit from
changes to the language, there are some changes which I believe would
make sense.

If I were to apply this change to C++, I would simply add an extension
to the existing language which allowed a switch to generate a warning
in each location a value is being passed by reference without having a
commensurate @ associated with it. That way developers can go in and
markup their code at each warning location to include the @ so that it
is visibly identifiable that the value going into that function is not
being passed by value, but by reference, and therefore it could be
updated.

I think it's a simple request, a logical extension, and something that
addresses a shortcoming in source code written in C++. But, that's
just my take on it. I could be wrong.

Alf P. Steinbach

unread,
May 4, 2016, 12:10:40 PM5/4/16
to
On 03.05.2016 19:26, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>> They *could* have done a lot of things. But your method violates the
>> concept of a reference - not having to use special syntax in the code to
>> pass or use the reference.
>
> I WANT to use special syntax to pass by reference. I want it to show up
> in source code so I know it's a reference rather than a value pass.

template< class Type >
using Ref_ = Type&;

template< class Type >
class XRef_ // explicit reference
{
private:
Type* p_;
auto operator=( Ref_<const XRef_> ) -> Ref_<XRef_> = delete;

public:
auto object() -> Ref_<Type> { return *p_; }
operator Ref_<Type> () const { return object(); }
explicit XRef_( Ref_<Type> r ): p_( &r ) {}
};

template< class Type >
auto xref( Ref_<Type> r ) -> XRef_<Type> { return XRef_<Type>( r ); }

void foo( XRef_<int> x )
{ x.object() = 42; }

auto main() -> int
{
int a;
#ifdef TEST
foo( a ); //! Nope.
#endif
foo( xref( a ) );
}

I leave it as an exercise for the student to support conversion Derived
→ Base.


Cheers & hth.,

- Alf

Richard

unread,
May 4, 2016, 12:24:35 PM5/4/16
to
[Please do not mail me a copy of your followup]

Robert Wessel <robert...@yahoo.com> spake the secret code
<rq9jibhsj8pkffp0t...@4ax.com> thusly:

>That references cannot be null are a minor feature of
>references.

Actually it's a HUGE feature because it means that hundreds and
hundreds of defensive checks for NULL disappear from your code.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Rosario19

unread,
May 7, 2016, 12:18:43 AM5/7/16
to
On Tue, 3 May 2016 11:44:53 -0700 (PDT), "Rick C. Hodgin" wrote:

>My position is that references have utility in that you don't need to
>check if they're NULL, but they still operate the same way as a pointer
>under the hood, updating remote data. They also require less syntax on
>use in the target function, which is desirable while still carrying out
>remote data assignment. There's just no way to know if something is a
>reference or not without additional interrogation of the source code.

and if the pointer is NULL? [the sys has not memory for the obj]
i like all these NULL checks

Rosario19

unread,
May 7, 2016, 12:22:47 AM5/7/16
to
On Tue, 3 May 2016 20:36:30 +0200, Melzzzzz wrote:

>Operator overloading. Having c = a + b; is more convenient then
>c = &a + &b;

c = a + b

if the types of c, a, b are objects and not basic types
should mean already "&c = &a + &b"


Rosario19

unread,
May 7, 2016, 12:24:59 AM5/7/16
to
and reference has not objius use...
so reference is one error in the story of informatic...

Jorgen Grahn

unread,
May 7, 2016, 1:00:39 AM5/7/16
to
On Tue, 2016-05-03, K. Frank wrote:
...
> But Chris makes a good style suggestion: Pass by pointer
> (not by non-const reference) if the function might modify
> those arguments. (This is what I generally do. I either
> "forbid" the use of null -- and other invalid -- pointers,
> or test for them.)

That's what I used to do too, but after a discussion with someone here
I more or less stopped doing that, and embraced non-const reference
parameters.

In practice it works well. These cases are rare (especially if you
don't use them often as a possibly-faster substitute for return
values) and it's usually pretty clear from context what happens: you
tend to see at the call site that the function intends to modify
what's passed in.

Rick C. Hodgin

unread,
May 7, 2016, 10:21:20 AM5/7/16
to
On Saturday, May 7, 2016 at 12:24:59 AM UTC-4, Rosario19 wrote:
> On Sat, 07 May 2016 06:22:38 +0200, Rosario19 wrote:
>
> >On Tue, 3 May 2016 20:36:30 +0200, Melzzzzz wrote:
> >
> >>Operator overloading. Having c = a + b; is more convenient then
> >>c = &a + &b;
> >
> >c = a + b
> >
> >if the types of c, a, b are objects and not basic types
> >should mean already "&c = &a + &b"

This kind of syntax is silly. :-) My only interest in highlighting
the use of reference values in syntax is when they're passed as input
into functions, either directly or indirectly. I'd like to see that
they are entering a function as a non-const reference parameter (meaning
they might be updated).

> and reference has not objius use...
> so reference is one error in the story of informatic...

They remove the need to check for NULL because all reference params
come in guaranteed by the compiler to be non-NULL. The only way they
can be non-NULL is if some illegal and sneaky or tricky happens.

The syntax in the function which uses the reference is greatly
simplified while allowing remote data (data at the other end of a
pointer) to be updated as though it were local data.

My only issue is that these two look identical (except for the function
name), yet they are capable of doing completely different things:

func1(int a, int b, int c) { ... }
func2(int& a, int& b, int& c) { ... }

int a, b, c = 0;

func1(a, b, c);
func2(a, b, c);

There's no way to know without changing the syntax. It should be like
this:

func1(a, b, c);
func2(@a, @b, @c);

In this way it's obvious that a, b, and c in func2() are reference
parameters that may be updated. And the additional syntax of the
@a! would indicate it's a const reference that won't be updated,
and @a' means it could. I would also be open to @a# as an alternate
syntax (to indicate it is non-const, and then to use @a' or some
other form to indicate it's not const, but should not be updated
by convention rather than enforcement).

Rosario19

unread,
May 7, 2016, 1:14:25 PM5/7/16
to
On Sat, 7 May 2016 07:21:04 -0700 (PDT), "Rick C. Hodgin" wrote:

>They remove the need to check for NULL because all reference params
>come in guaranteed by the compiler to be non-NULL. The only way they
>can be non-NULL is if some illegal and sneaky or tricky happens.

i not see as you...
i see malloc or stack give the memory for create the obj
and *no one* can garantee that memory exist....

so the way of resolve the problem is see if &obj==NULL
and not the compiler that know that the memory for the obj exist..

because objects are created in run time too

Rick C. Hodgin

unread,
May 7, 2016, 2:58:29 PM5/7/16
to
The compiler guarantees that a pointer is not NULL when you use a
reference. It will not allow something by reference that is NULL.

int a, b, c;

These are not allocated at runtime by a runtime function, but rather
they exist by the mechanics of the machine (the stack). As such, you
will be guaranteed that you are able to use them when you try to use
them because the stack error would've already occurred before you got
to the place in your program where you were trying to use them.

The only way you can have a NULL is by someone doing something that
is not legal code, such as by passing a NULL input to a function that
is receives a reference parameter in that slot. In that case, the
language protocol has been violated and the error condition is the
result.

By using this secure feature, the only way that the function could
be fooled is if the virus had intimate knowledge of the runtime state
of the program because it would not be able to read the source code
to find out what value to use with the call.

And something SuperCat brought up has made me consider something
along the lines of what another user pointed out in comp.lang.c,
which is that there should be true security with regards to the
actual API entry points the application uses, so that they cannot
even be called unless they pass security scrutiny. And I am
considering how I could implement that feature in my CPU as I
think it's a truly brilliant suggestion.

But as for by-reference parameters, they have great utility because
they have simplified syntax, and there is then no need to consider
them ever being NULL in a compliant system. I view them as an
essential component of software development.

Rosario19

unread,
May 7, 2016, 3:51:05 PM5/7/16
to
On Sat, 7 May 2016 11:58:19 -0700 (PDT), "Rick C. Hodgin" wrote:
>On Saturday, May 7, 2016 at 1:14:25 PM UTC-4, Rosario19 wrote:
>> On Sat, 7 May 2016 07:21:04 -0700 (PDT), "Rick C. Hodgin" wrote:
>>
>> >They remove the need to check for NULL because all reference params
>> >come in guaranteed by the compiler to be non-NULL. The only way they
>> >can be non-NULL is if some illegal and sneaky or tricky happens.
>>
>> i not see as you...
>> i see malloc or stack give the memory for create the obj
>> and *no one* can garantee that memory exist....
>>
>> so the way of resolve the problem is see if &obj==NULL
>> and not the compiler that know that the memory for the obj exist..
>>
>> because objects are created in run time too
>
>The compiler guarantees that a pointer is not NULL when you use a
>reference. It will not allow something by reference that is NULL.
>
> int a, b, c;
>
>These are not allocated at runtime by a runtime function, but rather
>they exist by the mechanics of the machine (the stack).

i know if "int a,b,c;" are global than there is the "garantee" the
memory where they are exist

but if "int a,b,c;" is in the stack
[as local variables for one function] there is not such garantee...

>As such, you
>will be guaranteed that you are able to use them

there is for little size variable some "garantee" but enven in that
case if
int f(void){int a,b,c; a=1; f(); }
this should seg fault because "a" has no memory...

if you think that f() is one error, than exist function recursive have
need big memory on stack for calculate their finaly result...

>when you try to use
>them because the stack error would've already occurred before you got
>to the place in your program where you were trying to use them.
>
>The only way you can have a NULL is by someone doing something that
>is not legal code, such as by passing a NULL input to a function that
>is receives a reference parameter in that slot. In that case, the
>language protocol has been violated and the error condition is the
>result.
>
>By using this secure feature, the only way that the function could
>be fooled is if the virus had intimate knowledge of the runtime state
>of the program because it would not be able to read the source code
>to find out what value to use with the call.
>
>And something SuperCat brought up has made me consider something
>along the lines of what another user pointed out in comp.lang.c,
>which is that there should be true security with regards to the
>actual API entry points the application uses, so that they cannot
>even be called unless they pass security scrutiny. And I am
>considering how I could implement that feature in my CPU as I
>think it's a truly brilliant suggestion.
>
>But as for by-reference parameters,

i find "by-reference" as const
errors streets for informatic...

Rick C. Hodgin

unread,
May 7, 2016, 3:57:47 PM5/7/16
to
On Saturday, May 7, 2016 at 3:51:05 PM UTC-4, Rosario19 wrote:
> On Sat, 7 May 2016 11:58:19 -0700 (PDT), "Rick C. Hodgin" wrote:
> >On Saturday, May 7, 2016 at 1:14:25 PM UTC-4, Rosario19 wrote:
> >> On Sat, 7 May 2016 07:21:04 -0700 (PDT), "Rick C. Hodgin" wrote:
> >>
> >> >They remove the need to check for NULL because all reference params
> >> >come in guaranteed by the compiler to be non-NULL. The only way they
> >> >can be non-NULL is if some illegal and sneaky or tricky happens.
> >>
> >> i not see as you...
> >> i see malloc or stack give the memory for create the obj
> >> and *no one* can garantee that memory exist....
> >>
> >> so the way of resolve the problem is see if &obj==NULL
> >> and not the compiler that know that the memory for the obj exist..
> >>
> >> because objects are created in run time too
> >
> >The compiler guarantees that a pointer is not NULL when you use a
> >reference. It will not allow something by reference that is NULL.
> >
> > int a, b, c;
> >
> >These are not allocated at runtime by a runtime function, but rather
> >they exist by the mechanics of the machine (the stack).
>
> i know if "int a,b,c;" are global than there is the "garantee" the
> memory where they are exist
>
> but if "int a,b,c;" is in the stack
> [as local variables for one function] there is not such garantee...

If they are local variables, it is guaranteed they will exist. If
they are pointers to those types, then it is possible they will not
exist, even though it is guaranteed the pointer itself WILL exist,
as it can always be tested for NULL, for example.

int a;
int* b = (int*)malloc(sizeof(int));
// a and b always exist
// But, it's possible *b doesn't because it was allocated at runtime

> >As such, you
> >will be guaranteed that you are able to use them
>
> there is for little size variable some "garantee" but enven in that
> case if
> int f(void){int a,b,c; a=1; f(); }
> this should seg fault because "a" has no memory...

Yes, but the segfault occurs before you are able to use a. If, however,
you are able to use a (because you are on that line of source code),
then you know it exists.

That's my point, the error would've occurred BEFORE you were able to
use a.

> if you think that f() is one error, than exist function recursive have
> need big memory on stack for calculate their finaly result...

If you have a recursive function that could exceed the stack, then it
is a requirement that you guard against that by monitoring your depth.
If it gets too high, then you implement a protocol which fails further
recursion.

> >when you try to use
> >them because the stack error would've already occurred before you got
> >to the place in your program where you were trying to use them.
> >
> >The only way you can have a NULL is by someone doing something that
> >is not legal code, such as by passing a NULL input to a function that
> >is receives a reference parameter in that slot. In that case, the
> >language protocol has been violated and the error condition is the
> >result.
> >
> >By using this secure feature, the only way that the function could
> >be fooled is if the virus had intimate knowledge of the runtime state
> >of the program because it would not be able to read the source code
> >to find out what value to use with the call.
> >
> >And something SuperCat brought up has made me consider something
> >along the lines of what another user pointed out in comp.lang.c,
> >which is that there should be true security with regards to the
> >actual API entry points the application uses, so that they cannot
> >even be called unless they pass security scrutiny. And I am
> >considering how I could implement that feature in my CPU as I
> >think it's a truly brilliant suggestion.
> >
> >But as for by-reference parameters,
>
> i find "by-reference" as const
> errors streets for informatic...

I may be misunderstanding what you mean, but by-reference doesn't have
to be const. The two are separate, and much of their utility comes in
the non-const form.

Rosario19

unread,
May 7, 2016, 4:04:31 PM5/7/16
to
On Sat, 7 May 2016 12:57:37 -0700 (PDT), "Rick C. Hodgin" wrote:

>I may be misunderstanding what you mean, but by-reference doesn't have
>to be const. The two are separate, and much of their utility comes in
>the non-const form.

references and consts
are two words not good for the informatic
are wrong ways in how i see them

Rosario19

unread,
May 7, 2016, 4:04:58 PM5/7/16
to
On Sat, 7 May 2016 12:57:37 -0700 (PDT), "Rick C. Hodgin" wrote:

>I may be misunderstanding what you mean, but by-reference doesn't have
>to be const. The two are separate, and much of their utility comes in
>the non-const form.

"reference" and "const"

Öö Tiib

unread,
May 7, 2016, 4:32:20 PM5/7/16
to
On Saturday, 7 May 2016 17:21:20 UTC+3, Rick C. Hodgin wrote:
>
> My only issue is that these two look identical (except for the function
> name), yet they are capable of doing completely different things:
>
> func1(int a, int b, int c) { ... }
> func2(int& a, int& b, int& c) { ... }
>
> int a, b, c = 0;
>
> func1(a, b, c);
> func2(a, b, c);
>
> There's no way to know without changing the syntax. It should be like
> this:
>
> func1(a, b, c);
> func2(@a, @b, @c);

We understood that, we just are unsure if it is improvement. Can you for
a variety bring some motivating examples? Where you really need functions
with 3 or more "in-out" parameters? What are those functions doing?

C++ has some mechanics to make function calls more expressive. For example
when there is a function with one "in" parameter, one "in-out" parameter
and one "out" parameter then I expect the designer of interface to arrange
the call like that in C++:

out_parameter = in_out_parameter.function( in_parameter );

If there are two "in-out" parameters then one of those has to be
passed as reference or pointer to non-const however that situation
is typically obvious from function's name. Situation with three or
more in-out parameters however feels complicated regardless if
there are some special indication of those or not. IOW it tends to
work fine like it is in practice.

Rick C. Hodgin

unread,
May 7, 2016, 4:48:54 PM5/7/16
to
The place where it occurred to me was in source code like this (a
greatly simplified example):

// Parse the string
void some_function(char* data, int length)
{
int offset;

for (offset = 0; offset < length; )
{
// Skip any leading whitespaces
skip_whitepsaces(data, offset, length);

// Parse something else
// Skip past the parsed data
}
}

At first glance, I was wondering why offset was being used, and why data
wasn't being updated. It took me a couple seconds to realize that offset
must be being passed by reference, and is being updated.

Had it been written like this, I would've known without even thinking
about it:

skip_whitepsaces(data, @offset, length);

I would've recognized that character there and said silently to myself,
"Ah ha!"

It was after I read that source code line I had the thought, because
after the brief few seconds where I was puzzled, and then when I came
to the realization, I remembered other times in my past where I had
encountered similar things, each time winding up doing one of these
things:

http://www.omsmedia.com/wordpress/wp-content/uploads/2013/05/kid-head-slap.jpg

It got me to thinking about why do we have "int& a" rather than
something else? We use & for address-of, which is associated with a
pointer, but we also use it for a reference? Really? It seemed
backwards.

And, I remembered how I had decided to fix this issue in my CAlive
language I'm working on:

https://groups.google.com/forum/#!topic/caliveprogramminglanguage/mFVHvtDTmo8

I introduce @, and allow @ or & to be used for a reference or pointer
form, allowing a new relaxation, and one which I hope will spawn a
switch to where pointers being to use @var for the equivalent of what
today is &var, and that we will begin using &var for the equivalent
of what today is a pass-by-reference syntax, that which I have here
been proposing should use the new @var form in C/C++.

In CAlive I want them to be reversed because I think they make more
sense the other way around, but I am not prepared to break backward
compatibility, so I would allow either at both and resolve the ambiguity
by the declaration type, or the type of the body definition if the
declaration is not present (as CAlive also has plans to remove the
need for forward declarations).

And, to be clear, CAlive is a somewhat object-oriented version of C.
It is much less than C++, but brings to C many of the essential elements
of C++ (as I see them, and there's room for expansion or contraction as
other people provide input).

Jerry Stuckle

unread,
May 7, 2016, 7:52:34 PM5/7/16
to
On 5/3/2016 2:44 PM, Rick C. Hodgin wrote:
> On Tuesday, May 3, 2016 at 1:56:16 PM UTC-4, Chris Vine wrote:
>> On Tue, 3 May 2016 10:26:22 -0700 (PDT)
>> "Rick C. Hodgin" <rick.c...@gmail.com> wrote:
>>> On Tuesday, May 3, 2016 at 1:04:21 PM UTC-4, Jerry Stuckle wrote:
>>>> They *could* have done a lot of things. But your method violates
>>>> the concept of a reference - not having to use special syntax in
>>>> the code to pass or use the reference.
>>>
>>> I WANT to use special syntax to pass by reference. I want it to show
>>> up in source code so I know it's a reference rather than a value pass.
>>
>> "I WANT".
>>
>> Its original purpose was as I understand it to permit efficient operator
>> overloading with a natural syntax. A little googling would have led you
>> here: http://www.stroustrup.com/bs_faq2.html#pointers-and-references
>>
>> If you want a special syntax, use pointers. They have been there since
>> the beginning.
>
> My position is that references have utility in that you don't need to
> check if they're NULL, but they still operate the same way as a pointer
> under the hood, updating remote data. They also require less syntax on
> use in the target function, which is desirable while still carrying out
> remote data assignment. There's just no way to know if something is a
> reference or not without additional interrogation of the source code.
>
> Best regards,
> Rick C. Hodgin
>

That is an incorrect statement. For instance:

#include <iostream>

void callByRef(int & cr) {
std::cout << "The address of cr is " << &cr << std::endl;
return;
}

int main (void) {
int *pi = NULL;
int &ri = *pi;
callByRef(ri);
return 0;
}

Output:
The address of cr is 0

--
==================
Remove the "x" from my email address
Jerry Stuckle
jstu...@attglobal.net
==================

Rick C. Hodgin

unread,
May 7, 2016, 8:20:43 PM5/7/16
to
Well of course. We're back to the pointer issue. Anytime pointers are
involved you need to check the pointer before you use it. If you use
references with real values, or pointer values where the pointer has
already been validated, then you don't need to check when the associated
reference is used.

int main (int argc, char* argv[])
{
int *pi = NULL;

if (pi)
{
// We're good
int &ri = *pi;
callByRef(ri);
return 0;

} else {
// Invalid pointer
std::cout << "NULL pointer" << std::endl;
return -1;

Jerry Stuckle

unread,
May 7, 2016, 9:22:02 PM5/7/16
to
But you said it was impossible to have a reference to NULL. I just
pointed out that is NOT the fact. So your argument is false.

The function has no idea what was passed to it. Unlike a copy (which is
always allocated on the stack), a reference *can* point at NULL - just
like a pointer.

Rick C. Hodgin

unread,
May 7, 2016, 10:01:03 PM5/7/16
to
What I said was: "[References] remove the need to check for NULL because
all reference params come in guaranteed by the compiler to be non-NULL.
The only way they can be non-NULL is if some illegal and sneaky or tricky
[thing] happens."

> The function has no idea what was passed to it. Unlike a copy (which is
> always allocated on the stack), a reference *can* point at NULL - just
> like a pointer.

There's protocol, Jerry. People can always weasel and snake their way
around and force things that ultimately cause much harm.

And as I say, whenever you work with pointers you must check them. Doing
so in your contrived example would've prevented the issue. It wasn't a
failure on the reference side, or in the compiler, but in the way the
reference was used without first checking the pointer.

-----
You did bring up a point that I was surprised to see in a C++ compiler, by
the way. When you used "int &ri = *pi;" I was surprised the compiler allowed
the runtime de-reference on a NULL to be stored in a reference. While I
recognize it's just using the address that's in use, I would've thought the
compiler would at least do a runtime check on the pointer and in that way
generate the error there where the NULL pointer is being de-referenced. I
also think the C++ compiler _should_ do that. Doing so would've caught bugs
like this one in your example.

Jerry Stuckle

unread,
May 7, 2016, 11:08:30 PM5/7/16
to
And I proved you wrong. There is nothing illegal in my code, nor is
there a sneaky trick. It's just a very simplified example of what can
easily happen, and the reference param is NULL.

I could have done something fancier - like set up a linked list and pass
a reference to a list element. But one past the end of the list would
have been a reference to NULL.

I just tried to keep it simple enough for anyone to understand.



>> The function has no idea what was passed to it. Unlike a copy (which is
>> always allocated on the stack), a reference *can* point at NULL - just
>> like a pointer.
>
> There's protocol, Jerry. People can always weasel and snake their way
> around and force things that ultimately cause much harm.
>

No "weasel and snake their way", Rick. Something which can easily happen.

> And as I say, whenever you work with pointers you must check them. Doing
> so in your contrived example would've prevented the issue. It wasn't a
> failure on the reference side, or in the compiler, but in the way the
> reference was used without first checking the pointer.
>

But that doesn't always happen. And yes, it is a contrived example. I
wanted to ensure it was simple enough for anyone to understand. But it
shows your statement is false.

> -----
> You did bring up a point that I was surprised to see in a C++ compiler, by
> the way. When you used "int &ri = *pi;" I was surprised the compiler allowed
> the runtime de-reference on a NULL to be stored in a reference. While I
> recognize it's just using the address that's in use, I would've thought the
> compiler would at least do a runtime check on the pointer and in that way
> generate the error there where the NULL pointer is being de-referenced. I
> also think the C++ compiler _should_ do that. Doing so would've caught bugs
> like this one in your example.
>
> Best regards,
> Rick C. Hodgin
>

The compiler never checks pointers. As with C, it is the programmer's
responsibility to ensure the pointers contain valid addresses. C++
doesn't hold your hand any more than C does.

Rick C. Hodgin

unread,
May 7, 2016, 11:28:24 PM5/7/16
to
You're de-referencing a NULL pointer, which is illegal. The fact that the
compiler did not catch it at runtime highlights a flaw in the compiler and
or C++ standard, because the error you created should never have been
allowed to occur.
> The compiler never checks pointers. As with C, it is the programmer's
> responsibility to ensure the pointers contain valid addresses. C++
> doesn't hold your hand any more than C does.

I believe the C++ compiler should in this case. When you're de-referencing
a pointer that will then be passed as a reference, the compiler should inject
code to perform the NULL check right there, to catch the error at its cause,
just as if the code had been used as "int i = *pi;" would've done.

Rosario19

unread,
May 7, 2016, 11:39:28 PM5/7/16
to
On Sat, 7 May 2016 20:28:09 -0700 (PDT), "Rick C. Hodgin" wrote:
>I believe the C++ compiler should in this case. When you're de-referencing
>a pointer that will then be passed as a reference, the compiler should inject
>code to perform the NULL check right there, to catch the error at its cause,

so each time de-reference it has to check if it is NULL?

no... the time only when the pointer change
value if it is used as adrress with *

but when do you sleep?

Rick C. Hodgin

unread,
May 7, 2016, 11:54:41 PM5/7/16
to
On Saturday, May 7, 2016 at 11:39:28 PM UTC-4, Rosario19 wrote:
> On Sat, 7 May 2016 20:28:09 -0700 (PDT), "Rick C. Hodgin" wrote:
> >I believe the C++ compiler should in this case. When you're de-referencing
> >a pointer that will then be passed as a reference, the compiler should inject
> >code to perform the NULL check right there, to catch the error at its cause,
>
> so each time de-reference it has to check if it is NULL?

It won't actually check if it's NULL as by injecting a test, but it
will try to read from the de-referenced location, which would signal
the error just as it would've had it been used in an "int i = *pi;"
version.

> no... the time only when the pointer change
> value if it is used as adrress with *

That's the way the compiler works today, and Jerry's code failed to
check for a NULL pointer, and therefore the bug came through. I don't
think it should be that way. Whenever you're passing the result of a
pointer's value as a by-reference value, it should test the value
before arbitrarily sending the value. It will be a minor performance
hit, but negligible for the extra safety it provides.

You could, of course, also bypass the performance hit by assigning it
only one time, and from that point forward passing the reference. It
would remain valid so long as the pointer remains valid.

> but when do you sleep?

When I'm tired. :-) It's almost midnight here. I'm actually heading
to bed here in just a few.

> >just as if the code had been used as "int i = *pi;" would've done.

red floyd

unread,
May 8, 2016, 1:04:49 AM5/8/16
to
No, because initializing the reference invokes UB. Dereferencing
a NULL pointer is always UB. At that point, anything can happen,
including, as you know, *appearing* to "work properly".



Paavo Helde

unread,
May 8, 2016, 1:44:14 AM5/8/16
to
This program exhibits undefined behavior, so it is not guaranteed at all
that it outputs "The address of cr is 0" (or that it outputs anything at
all). A debugging implementation might have terminated the program
already earlier.

So I agree with Rick in that "references have utility in that you don't
need to check if they're NULL".

In more detail, there is no need to check against "NULL references" because

a) the program must have exhibited UB first, so it's not sure how it
behaves and it's not guaranteed that the check is reached at all.

b) the check may be optimized out by the compiler as it relies on UB,
meaning it is not reliable.

c) if the check triggers, there is not much to do: you know that your
program state is invalid so about the only sane thing to do is to call
std::terminate(). But this will happen most probably anyway in the next
code line which tries to use the object, so there is not much point.

d) if the check triggers and the program continues to run, then you have
just hidden an UB bug in the program, which may expose itself again in a
different way in the most inappropriate time.

The correct place to check is to check the pointer before creating the
reference:

int main (void) {
int *pi = NULL;
assert(pi);
int &ri = *pi;
callByRef(ri);
}

Checking against "NULL references" becomes viable only if the
implementation defines the behavior, so that it's not UB any more. For
example, MS seems to have done so in MSVC as they check against
this==NULL in some of their code (implementation of MFC
CWnd::GetSafeHwnd() et al). However, I believe this behavior is not
publicly documented, which means it can change in the next compiler
version or whatever and only MSVC itself can rely on it.

As to why "NULL references" are undefined behavior, see 8.3.2/5 [dcl.ref]:

<quote>
A reference shall be initialized to refer to a valid object or function.
[ Note: in particular, a null reference cannot exist in a well-defined
program, because the only way to create such a reference would be to
bind it to the “object” obtained by indirection through a null pointer,
which causes undefined behavior.
</quote>


Öö Tiib

unread,
May 8, 2016, 1:50:45 AM5/8/16
to
The C++ standard however proves you wrong. (8.3.2/4 "References"):

| Note: in particular, a null reference cannot exist in a
| well-defined program, because the only way to create such a reference
| would be to bind it to the "object" obtained by dereferencing a null
| pointer, which causes undefined behavior.

That is exactly what you did. Therefore what you have there is not
reference to NULL but a reference to demons from your nose.

>
> I could have done something fancier - like set up a linked list and pass
> a reference to a list element. But one past the end of the list would
> have been a reference to NULL.

So it would have been same defect.
It feels that you are trolling again by posting code with undefined
behavior.

Öö Tiib

unread,
May 8, 2016, 4:11:48 AM5/8/16
to
It was really named "skip_whitepsaces"? It has indeed odd for C++
signature. More usual to C++ is to use iterators or ranges on such
cases instead of indexes, lengths and offsets.
Most readable calling for same (IMHO) would be something among:

start.skip_whitespace(finish);

start.skip(whitespaces, finish);

range.left_trim_whitespace();

range.left_trim(whitespaces);


Those may be not convenient to achieve in C++ sometimes but
would look more obvious what there is going on.

>
> It was after I read that source code line I had the thought, because
> after the brief few seconds where I was puzzled, and then when I came
> to the realization, I remembered other times in my past where I had
> encountered similar things, each time winding up doing one of these
> things:
>
> http://www.omsmedia.com/wordpress/wp-content/uploads/2013/05/kid-head-slap.jpg
>
> It got me to thinking about why do we have "int& a" rather than
> something else? We use & for address-of, which is associated with a
> pointer, but we also use it for a reference? Really? It seemed
> backwards.

Perhaps then try it out if more such symbols makes it possible to
achieve more readable code.

>
> And, I remembered how I had decided to fix this issue in my CAlive
> language I'm working on:
>
> https://groups.google.com/forum/#!topic/caliveprogramminglanguage/mFVHvtDTmo8
>
> I introduce @, and allow @ or & to be used for a reference or pointer
> form, allowing a new relaxation, and one which I hope will spawn a
> switch to where pointers being to use @var for the equivalent of what
> today is &var, and that we will begin using &var for the equivalent
> of what today is a pass-by-reference syntax, that which I have here
> been proposing should use the new @var form in C/C++.
>
> In CAlive I want them to be reversed because I think they make more
> sense the other way around, but I am not prepared to break backward
> compatibility, so I would allow either at both and resolve the ambiguity
> by the declaration type, or the type of the body definition if the
> declaration is not present (as CAlive also has plans to remove the
> need for forward declarations).
>
> And, to be clear, CAlive is a somewhat object-oriented version of C.
> It is much less than C++, but brings to C many of the essential elements
> of C++ (as I see them, and there's room for expansion or contraction as
> other people provide input).

Does your language have also "this" like in C++? Perhaps make it
a reference. It is pointer in C++ that can't be changed and may not
be NULL so it is actually a reference with pointer syntax.

Bo Persson

unread,
May 8, 2016, 5:02:35 AM5/8/16
to
I believe this is the same as when Qt does it - the framework developers
try to handle bug reports by "fixing" the code. They likely never
checked this with the compiler team.


Bo Persson


Öö Tiib

unread,
May 8, 2016, 6:56:09 AM5/8/16
to
Often such "bug fixes" that rely on black wizardry with undefined behaviors
are asshole-originated. For example some unskilled manager failed to dodge
a blame and so his team has to implement that hack or to fail.

Same can happen with compiler developers. For example when some benchmark
code (that management has accepted) contains undefined behavior then it
can be easier (for compiler team) to achieve the expected outcome instead
of trying to argue that it is because of defect in benchmark.

Jerry Stuckle

unread,
May 8, 2016, 11:20:11 AM5/8/16
to
No, it is not illegal. It actually is undefined behavior. And the
compiler is not *supposed* to catch it at runtime.

What you don't get is, both C and C++ require a higher level of
responsibility from the programmer. Neither generates unnecessary
runtime check code. That's YOUR job.

It's no different than going out of bounds on an array. That's the
programmer's problem, not the language's.

<snip>

>>
>> The compiler never checks pointers. As with C, it is the programmer's
>> responsibility to ensure the pointers contain valid addresses. C++
>> doesn't hold your hand any more than C does.
>
> I believe the C++ compiler should in this case. When you're de-referencing
> a pointer that will then be passed as a reference, the compiler should inject
> code to perform the NULL check right there, to catch the error at its cause,
> just as if the code had been used as "int i = *pi;" would've done.
>
> Best regards,
> Rick C. Hodgin
>

What you believe is immaterial, Rick. Neither C nor C++ generates
unnecessary code to check for programming errors. If such a test is
required, it is the responsibility of the programmer.

And it also will not generate code to check "int i = *pi;". That is
also undefined behavior.

Jerry Stuckle

unread,
May 8, 2016, 11:25:36 AM5/8/16
to
Yes, and it is "undefined behavior" - not "illegal". A huge difference.

>>
>> I could have done something fancier - like set up a linked list and pass
>> a reference to a list element. But one past the end of the list would
>> have been a reference to NULL.
>
> So it would have been same defect.
> It feels that you are trolling again by posting code with undefined
> behavior.
>

But it is not "illegal". No trolling - just pointing out that Rick's
statement that a reference cannot be NULL is incorrect.

<snip>

Jerry Stuckle

unread,
May 8, 2016, 11:26:48 AM5/8/16
to
That is correct. It is undefined behavior. But it is not illegal, and
it can happen - despite Rick's claim.

Jerry Stuckle

unread,
May 8, 2016, 11:28:57 AM5/8/16
to
That all is well and good. But undefined behavior does not mean a
reference cannot be NULL. Just that there is no guarantee what will
happen if it is NULL.

I don't disagree there are better ways of handling it. But that doesn't
always happen, does it?

Rick C. Hodgin

unread,
May 8, 2016, 12:58:13 PM5/8/16
to
On Sunday, May 8, 2016 at 11:20:11 AM UTC-4, Jerry Stuckle wrote:
> On 5/7/2016 11:28 PM, Rick C. Hodgin wrote:
> > You're de-referencing a NULL pointer, which is illegal. The fact that the
> > compiler did not catch it at runtime highlights a flaw in the compiler and
> > or C++ standard, because the error you created should never have been
> > allowed to occur.
>
> No, it is not illegal.

Scarcely a difference, Jerry. And it still fits my definition of when
references can be NULL.

Here's something for you to try to educate yourself:

Create a legal and valid coding example (one that doesn't involve
UB) where you can legitimately create a NULL reference in C++.

> It actually is undefined behavior. And the
> compiler is not *supposed* to catch it at runtime.

I said it, "highlights a flaw in the compiler and or C++ standard,"
because in my estimation the compiler should catch those things. Since
references are never supposed to be NULL, passing a value as a reference
derived from a pointer should enforce the non-NULL nature of the pointer
by doing a simple memory read at that address. It would prevent this hole
you've exploited via the arena of illegal coding practices, which you
will say is only "UB" and not "illegal."

It's fundamental.

> What you don't get is, both C and C++ require a higher level of
> responsibility from the programmer. Neither generates unnecessary
> runtime check code. That's YOUR job.

What you don't get, and never seem to get, is that I don't care what
it's doing today. I'm looking toward what it SHOULD be doing because
I don't want 40 more years to pass by and we're still using legacy
baggage designed in the 1970s because of the limitations of those
machines back in the day.

I want a language that is very much C/C++ -like, but without some of
the peculiarities we are forced to deal with for legacy reasons. I
think the C Standard, and that which fed into the C++ standard, take
a backwards approach on things. I think there should be defined a
core set of abilities which are guaranteed, and then you can add on
additional extensions and relaxations on top of that core, but within
the core you address specific needs of data processing on the target
for which that core was written (a two's complement machine with same-
sized pointers, for example).

> It's no different than going out of bounds on an array. That's the
> programmer's problem, not the language's.

In this case, that was my point exactly, because we're dealing with what
exists today in C++. You should've checked for NULL so as to never have
created the illegal reference in the first place.

> > I believe the C++ compiler should in this case. When you're de-referencing
> > a pointer that will then be passed as a reference, the compiler should inject
> > code to perform the NULL check right there, to catch the error at its cause,
> > just as if the code had been used as "int i = *pi;" would've done.
>
> What you believe is immaterial, Rick.

I have no desire to wallow in what we have today, Jerry. I'm looking at
fundamental requirements of data processing, and I'm constructing CAlive
to begin there.

> Neither C nor C++ generates
> unnecessary code to check for programming errors. If such a test is
> required, it is the responsibility of the programmer.

In C/C++ that's the case. I'm looking to the future. I'm looking for
more. I wonder if you'll ever be able to grasp that concept, Jerry?

> And it also will not generate code to check "int i = *pi;". That is
> also undefined behavior.

Since you didn't get it, I'll be more clear: my point was the compiler
should try to reference data at the pointer's location before assigning
it to a reference.

-----
This will be my last reply to you, Jerry. Possibly the last one ever.
I wish you well, so I offer you a bit of advice: seek the Lord's guidance
before you reply to people. You'll find so much of what you write is
designed solely to be argumentative and obstinate, and in no way helpful.
You cause much harm in the forums you post because of your horrendous
attitude and large self-satiating ego. If you don't bring those aspects
of your character into check, they will be your undoing because they will
continuously lead you into all manner of places where there is no profit,
to places no person should ever go.

You have professed to be a Christian, so I advise you: humble yourself
before the Lord, Jerry. And then go forth.

red floyd

unread,
May 8, 2016, 1:19:34 PM5/8/16
to
But once UB has occurred, it doesn't matter what the output is. It's
just as perfectly legal for said program to segfault. Then you wouldn't
get your "correct output".


Wouter van Ooijen

unread,
May 8, 2016, 2:03:29 PM5/8/16
to
> Since you didn't get it, I'll be more clear: my point was the compiler
> should try to reference data at the pointer's location before assigning
> it to a reference.

That would catch only a small subset of illegal pointers/references. You
can of course implemented it in your own language, but for me that
language would not be acceptable as a high-performance (in terms of
execution speed) systems programming language. I am glad C++ has not
taken that route.

You might argue that with increasing CPU performance the
high-preformance issue will become irrelevant over time, but
- single-CPU perfromance is stalling
- whatever the level of performance, some uses will require the last
drop of juice from the metal, so we need a language that does exactly
that. This might not be the language for everyone, but hey, there is C#,
Java, Python, and your language might be the next! (But it will probably
not be my language)

Wouter van Ooijen

Rick C. Hodgin

unread,
May 8, 2016, 3:23:19 PM5/8/16
to
On Sunday, May 8, 2016 at 2:03:29 PM UTC-4, Wouter van Ooijen wrote:
> > Since you didn't get it, I'll be more clear: my point was the compiler
> > should try to reference data at the pointer's location before assigning
> > it to a reference.
>
> That would catch only a small subset of illegal pointers/references.

To my consideration on this matter, it would catch all that would be the
result of the compiler directly passing along something that it knows is
invalid. All other cases where there are illegal pointers/references
would come only from the application not following a proper protocol for
the use of resources. But this particular one stems from the compiler
failing to enforce something that must be true (that the reference
cannot be non-NULL).

> You
> can of course implemented it in your own language, but for me that
> language would not be acceptable as a high-performance (in terms of
> execution speed) systems programming language. I am glad C++ has not
> taken that route.

It would require one cache read, which the application is likely doing
anyway. And, there could be an optimization flag which removes those
checks in favor of execution speed.

> You might argue that with increasing CPU performance the
> high-preformance issue will become irrelevant over time, but
> - single-CPU perfromance is stalling
> - whatever the level of performance, some uses will require the last
> drop of juice from the metal, so we need a language that does exactly
> that. This might not be the language for everyone, but hey, there is C#,
> Java, Python, and your language might be the next! (But it will probably
> not be my language)
>
> Wouter van Ooijen

I appreciate your input and thinking. I consider such things, but I
value the time spent by developers in writing software more than final
execution speed.

My compiler framework is called "Rapid Development Compiler," which is
RDC for short. It is that part which has strong ties to debugging. I
ultimately intend to also create a follow-on product called "Rapid
Engine Compiler" which is designed around creating exceedingly highly
optimized code, with RDC maintaining only _some_ optimization abilities.

My goals are in helping developers write good code. Once they get it
debugged, then it should go to the next phase. It's an evolution,
starting with exceedingly high debugging tools and abilities first, and
then moving through a migration into raw performance which, all things
being equal, will continue with the source code not being changed. But,
at each optimization level there can be introduced new aspects of the
code's implementation which do introduce bugs.

It's where I'm headed with CAlive. They're my ultimate goals for those
tools.

Wouter van Ooijen

unread,
May 8, 2016, 3:52:43 PM5/8/16
to
Op 08-May-16 om 9:23 PM schreef Rick C. Hodgin:
In that case you should probably look more in the direction of managed
languages. When I must do non-critical desktop work I prefer Python.

> My compiler framework is called "Rapid Development Compiler," which is
> RDC for short. It is that part which has strong ties to debugging. I
> ultimately intend to also create a follow-on product called "Rapid
> Engine Compiler" which is designed around creating exceedingly highly
> optimized code, with RDC maintaining only _some_ optimization abilities.
>
> My goals are in helping developers write good code. Once they get it
> debugged, then it should go to the next phase. It's an evolution,
> starting with exceedingly high debugging tools and abilities first, and
> then moving through a migration into raw performance which, all things
> being equal, will continue with the source code not being changed. But,
> at each optimization level there can be introduced new aspects of the
> code's implementation which do introduce bugs.
>
> It's where I'm headed with CAlive. They're my ultimate goals for those
> tools.

Succes. If you ever target small micro-controllers I might try it. But
on those chips a heap is a definite no-no, and everything that is less
efficient than C (in speed or size) is frowned upon. Even C++ is often
(falsly) considered a bad idea.

Wouter

Rick C. Hodgin

unread,
May 8, 2016, 4:12:56 PM5/8/16
to
I have defined a managed type in my language as well. I also have a var
type which takes on the identity of the last thing that was stored into
it, including some built-in classes. In order to be used in context, it
is consistently type checked against the target making it take a small
performance hit, but where the ability to have a managed, discriminating
type is desirable, it can be quite nice.

> > My compiler framework is called "Rapid Development Compiler," which is
> > RDC for short. It is that part which has strong ties to debugging. I
> > ultimately intend to also create a follow-on product called "Rapid
> > Engine Compiler" which is designed around creating exceedingly highly
> > optimized code, with RDC maintaining only _some_ optimization abilities.
> >
> > My goals are in helping developers write good code. Once they get it
> > debugged, then it should go to the next phase. It's an evolution,
> > starting with exceedingly high debugging tools and abilities first, and
> > then moving through a migration into raw performance which, all things
> > being equal, will continue with the source code not being changed. But,
> > at each optimization level there can be introduced new aspects of the
> > code's implementation which do introduce bugs.
> >
> > It's where I'm headed with CAlive. They're my ultimate goals for those
> > tools.
>
> Succes. If you ever target small micro-controllers I might try it. But
> on those chips a heap is a definite no-no, and everything that is less
> efficient than C (in speed or size) is frowned upon. Even C++ is often
> (falsly) considered a bad idea.
>
> Wouter

Unlike C or C++, with CAlive I intend to create a core compiler which is a
fully compliant language implementation in a VM. As such, my design tools
will allow people to write code and test it in the VM as per the needs of
the language, and then ultimately port it to their favorite existing tool
which can be used on whatever the target is.

I have some alternate syntax extensions which can be suppressed by using
various flags, but if they are use I intend to write a tool which can
generate an output file with the commensurate C/C++ code as applicable.

We'll see how it goes. It's been a long time in the planning. I'm
currently working on a set of precursor tools for it (assembler and
basic C compiler) which will be used to create the rest of the toolkit.
My goals are to have it beginning to work next year, and completed by
2020. If I get other people helping me, it would go faster... but we'll
see how that pans out over time.

Rick C. Hodgin

unread,
May 8, 2016, 4:38:27 PM5/8/16
to
On Sunday, May 8, 2016 at 4:12:56 PM UTC-4, Rick C. Hodgin wrote:
> Unlike C or C++, with CAlive I intend to create a core compiler which is a
> fully compliant language implementation in a VM. As such, my design tools
> will allow people to write code and test it in the VM as per the needs of
> the language, and then ultimately port it to their favorite existing tool
> which can be used on whatever the target is.

To be clear about this part, I will release with each release of the CAlive
spec, a VM that possesses all of the support for the language, so people
can immediately test out their code changes without having to wait for the
actual machine-specific compiler to be implemented. Though, for all of
the platforms I intended to personally support (i686, AMD64, ARM), they
will also be released almost immediately after the VM is fully functional.

Jerry Stuckle

unread,
May 8, 2016, 6:42:30 PM5/8/16
to
On 5/8/2016 12:57 PM, Rick C. Hodgin wrote:
> On Sunday, May 8, 2016 at 11:20:11 AM UTC-4, Jerry Stuckle wrote:
>> On 5/7/2016 11:28 PM, Rick C. Hodgin wrote:
>>> You're de-referencing a NULL pointer, which is illegal. The fact that the
>>> compiler did not catch it at runtime highlights a flaw in the compiler and
>>> or C++ standard, because the error you created should never have been
>>> allowed to occur.
>>
>> No, it is not illegal.
>
> Scarcely a difference, Jerry. And it still fits my definition of when
> references can be NULL.
>

Yes, there is a huge difference between "illegal" and "undefined behavior".

> Here's something for you to try to educate yourself:
>
> Create a legal and valid coding example (one that doesn't involve
> UB) where you can legitimately create a NULL reference in C++.
>

As I said - the code was legal. Legal is NOT the same as undefined
behavior.

>> It actually is undefined behavior. And the
>> compiler is not *supposed* to catch it at runtime.
>
> I said it, "highlights a flaw in the compiler and or C++ standard,"
> because in my estimation the compiler should catch those things. Since
> references are never supposed to be NULL, passing a value as a reference
> derived from a pointer should enforce the non-NULL nature of the pointer
> by doing a simple memory read at that address. It would prevent this hole
> you've exploited via the arena of illegal coding practices, which you
> will say is only "UB" and not "illegal."
>

No, it is not a flaw in the compiler or the C++ standard. You may think
is is a flaw, but the standards committee disagrees. And yes, even the
standard says it is undefined behavior.

> It's fundamental.
>

Yes - it is fundamentally undefined behavior.

>> What you don't get is, both C and C++ require a higher level of
>> responsibility from the programmer. Neither generates unnecessary
>> runtime check code. That's YOUR job.
>
> What you don't get, and never seem to get, is that I don't care what
> it's doing today. I'm looking toward what it SHOULD be doing because
> I don't want 40 more years to pass by and we're still using legacy
> baggage designed in the 1970s because of the limitations of those
> machines back in the day.
>

No, you're looking at WHAT YOU THINK IT SHOULD BE DOING. If you want to
change the standard, you need to get on the standards committee and
convince others your way is better. Continually bitching here does not
good and annoys others.

> I want a language that is very much C/C++ -like, but without some of
> the peculiarities we are forced to deal with for legacy reasons. I
> think the C Standard, and that which fed into the C++ standard, take
> a backwards approach on things. I think there should be defined a
> core set of abilities which are guaranteed, and then you can add on
> additional extensions and relaxations on top of that core, but within
> the core you address specific needs of data processing on the target
> for which that core was written (a two's complement machine with same-
> sized pointers, for example).
>

Fine. Then create your own newsgroup for your new language. This one
is about C++, not something you want to create.

>> It's no different than going out of bounds on an array. That's the
>> programmer's problem, not the language's.
>
> In this case, that was my point exactly, because we're dealing with what
> exists today in C++. You should've checked for NULL so as to never have
> created the illegal reference in the first place.
>

Once again, it's not illegal. It's undefined behavior. Two different
things. And whether I should have checked it or not is immaterial - you
said it was impossible to get a reference to NULL. I just pointed out
where you are wrong.

>>> I believe the C++ compiler should in this case. When you're de-referencing
>>> a pointer that will then be passed as a reference, the compiler should inject
>>> code to perform the NULL check right there, to catch the error at its cause,
>>> just as if the code had been used as "int i = *pi;" would've done.
>>
>> What you believe is immaterial, Rick.
>
> I have no desire to wallow in what we have today, Jerry. I'm looking at
> fundamental requirements of data processing, and I'm constructing CAlive
> to begin there.
>

Then create a new newsgroup for your CAlive and discuss it there. In
case you haven't noticed, this is a C++ newsgroup.

>> Neither C nor C++ generates
>> unnecessary code to check for programming errors. If such a test is
>> required, it is the responsibility of the programmer.
>
> In C/C++ that's the case. I'm looking to the future. I'm looking for
> more. I wonder if you'll ever be able to grasp that concept, Jerry?
>

Then create your own newsgroup for CAlive.

>> And it also will not generate code to check "int i = *pi;". That is
>> also undefined behavior.
>
> Since you didn't get it, I'll be more clear: my point was the compiler
> should try to reference data at the pointer's location before assigning
> it to a reference.
>

I get it, Rick. But you don't get it. Part of the design of both C and
C++ is that the compiler does not test for things like this. These are
programmer errors, and both require more of the programmer.

> -----
> This will be my last reply to you, Jerry. Possibly the last one ever.
> I wish you well, so I offer you a bit of advice: seek the Lord's guidance
> before you reply to people. You'll find so much of what you write is
> designed solely to be argumentative and obstinate, and in no way helpful.
> You cause much harm in the forums you post because of your horrendous
> attitude and large self-satiating ego. If you don't bring those aspects
> of your character into check, they will be your undoing because they will
> continuously lead you into all manner of places where there is no profit,
> to places no person should ever go.
>
> You have professed to be a Christian, so I advise you: humble yourself
> before the Lord, Jerry. And then go forth.
>
> Best regards,
> Rick C. Hodgin
>

Rick, if you were a true Christian, you would follow Matthew 7:1 and
Luke 6:37.

Jerry Stuckle

unread,
May 8, 2016, 6:44:52 PM5/8/16
to
I never said anything about "correct output". Once again - I just
pointed out that it is possible.

Öö Tiib

unread,
May 10, 2016, 4:56:23 AM5/10/16
to
Of course there is huge difference, but for me the difference is like
between "a cat" and "an animal". IOW for me it has always been that
invoking "undefined behavior" is in a subset of things that are "illegal".

With ill-formed code the compiler is required to deliver a diagnostic about
it being illegal. With undefined behavior the compiler may do whatever.
That "whatever" includes compile-time or run-time diagnostic about the
code being illegal (on lot of cases compilers do that) but also it
includes silently producing a program that leaves appearance of working
and that a reference in it is a null reference.

So perhaps the disagreement here is about what is meant with "illegal".
It is loading more messages.
0 new messages