Register variables

S

sowmiyakc18

Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?
 
E

Eric Sosman

Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?

When to declare: As Richard Bos and Captain Corcoran say,
"Never. Well, hardly ever."

Significance: In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. Compilers have become much better at
making these decisions unaided, and such hints can be counter-
productive; many compilers ignore the hint. The remaining
effect of `register' is to declare that "No pointer can point
at this variable."

Conditions for passing: None, because `register' variables
are never passed to and from functions. Neither are `auto'
variables or `static' variables or any kinds of variables at
all: C functions receive and return *values*, not variables.
 
S

santosh

Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?

The qulifier 'register' used to suggest to the compiler that the
object concerned is likely to be heavily accessed and hence should
preferably be stored in a machine register. Registers are a collection
of very fast memory cells, most often within the processor itself.
Note that the use of register is merely a suggestion to the compiler,
which is free to ignore it.

Current compilers are, in almost all cases, better at allocating
registers than a programmer would be. Hence the register specifier is
mostly a relic from the past that you should not have to worry about.

As for it's restrictions, only auto objects can be qualified with
register and the address of a register qualified object may not be
taken, i.e. the & operator cannot be used.
 
R

Roberto Waltman

...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}


Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
U

user923005

Please clear my doubt. When do we declare a variable to be a register
variable? What is its significance? What are the conditions to be
adhered to when register variables are passed between functions?

The register keyword is only a suggestion, which compilers are free to
ignore.
However, it does place new restrictions on your code, because you
can't take the address of a register.

So:

void foo(void)
{
register int bar;
int *p = &bar; /* This is not allowed. Remove the register keyword on
bar and it's fine */
}

There may be some very rare instances where a compiler hint will
help. For the most part, it's silly to do it today.
 
G

Guest

...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

Here is a link to two of those compilers. You can check it out for
yourself: http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

<snip>
 
T

toby

Eric said:
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack,

Seems an unlikely and not very useful arrangement, since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).
and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
I

Ian Collins

Roberto said:
[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.
I haven't seen registers was preserved across function calls in thus
way, but I have seen registers used as 'in' and 'out' registers to avoid
pushing parameters before a function call.

The same concept is used by some RISC machines (Sparc being one example)
where register 'wheels' with in, working and out registers on each
'spoke' are used to optimise function calls.
 
G

Guest

Roberto said:
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

So for example, the following code snipped "should" work:

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}

On an emulated PDP11 running V7 UNIX, I get this:

1,$p
#include <stdio.h>

f1()
{
register a1, b1, c1;
a1 = 10;
b1 = 20;
c1 = a1 + b1;
f2();
}

f2()
{
register a2, b2, c2 ;
/* prints "10 + 20 = 30" */
printf("%d + %d = %d\n", a2, b2, c2);
}

main() { f2(); }
w
234
q
# cc test.c -o test
# ./test
0 + 0 = 0
#

(Its <stdio.h> does not declare printf; it only declares the functions
fopen, freopen, fdopen, ftell and fgets because of their return types.
But including it anyway doesn't cause any harm.)
 
R

Roberto Waltman

Here is a link to two of those compilers. You can check it out for
yourself: http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html

Thanks, I did some time ago. The two versions in Mr. Ritchie's page
predate the introduction of the "register" keyword. (Keyword list is
initialized in c00.c) I guess the expression I used, "original C
compiler", is to vague.


toby said:
Seems an unlikely and not very useful arrangement,

Not that I am recommending to do this, but this would have been a
"very useful arrangement" in systems with very limited resources.
Not different in principle from people finding out what unused opcodes
do in a processor and, against all logic, using them in their code.
There were times when 24K words was considered a lot of memory, and
instruction execution times were measured in microseconds, not
nanoseconds.
... since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

If these registers were indeed preserved across function calls, values
could have been transferred in both directions. I wrote "could have"
instead of the more definite "would have" because flow analysis could
allow reusing the register for a different purpose, although I doubt
these compilers did that.
And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).

Of course, guilty on all counts ...

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
R

Roberto Waltman

Harald van D?k said:
On an emulated PDP11 running V7 UNIX, I get this:
...

Thanks for checking.
main() { f2(); }
^
Better f1()

Is the default compiler in V7 a derivative of the original(s), or the
"Portable C Compiler"?
w
234
q
# cc test.c -o test
# ./test
0 + 0 = 0
#

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
J

John Byrns

Roberto Waltman said:
If these registers were indeed preserved across function calls, values
could have been transferred in both directions. I wrote "could have"
instead of the more definite "would have" because flow analysis could
allow reusing the register for a different purpose, although I doubt
these compilers did that.

Maybe I am not thinking about this correctly, but I don't see how these
register variables could possibly be used to return values? When the
function returns, the register preservation mechanism would overwrite
the registers with their original values would it not?


Regards,

John Byrns
 
G

Guest

Roberto said:
Thanks for checking.
^
Better f1()

Oh dear. Sorry, you're completely right, of course, and that does
result in the output you expected ("10 + 20 = 30").
Is the default compiler in V7 a derivative of the original(s), or the
"Portable C Compiler"?

There is a pcc script, and the runtime behaviour is the same when
compiling using that, so it's probably that, but I'll need to check
more carefully to be sure.
 
G

Guest

Harald said:
There is a pcc script, and the runtime behaviour is the same when
compiling using that, so it's probably that, but I'll need to check
more carefully to be sure.

No, the default compiler and pcc are different, although they have a
common preprocessor, optimiser and linker.
 
R

Roberto Waltman

John Byrns said:
..
Maybe I am not thinking about this correctly, but I don't see how these
register variables could possibly be used to return values? When the
function returns, the register preservation mechanism would overwrite
the registers with their original values would it not?

Not necessarily. The code generated by the compiler should preserve
only as much of the processor state as deemed necessary to continue
after a function call returns.
In a traditional register oriented architecture like the PDP-11, (to
limit the discussion to scenarios in which actually there *are*
registers,) this may include all registers, some, or none (other than
program counter and stack pointer.)
I would expect most compiler calling conventions to fall in the 'some'
group.

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
R

Roberto Waltman

Harald van D?k said:
... and that does
result in the output you expected ("10 + 20 = 30").

Bingo! Thanks. I pity the soul trying to debug code using this
"feature" through several levels of function calls...

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
 
K

Keith Thompson

toby said:
Eric said:
(e-mail address removed) wrote:
... When do we declare a variable to be a register
variable? ...
...In the Old Days, `register' was a hint that
the compiler should try to hold the variable in a CPU register
instead of in memory. ...

[Trivia][Folklore][Old-wife-tales]

Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack,

Seems an unlikely and not very useful arrangement, since the inner
function could not actually modify those variables - unless the user
wrote explicit code to save and restore them in the caller?

And of course this could only have been a "primeval C", since in this
manner it violates the semantics of what we today understand as C and
is not a compiler "feature" but a quirk of language design (or a bug).

It seems perfectly plausible that it would work that way, possibly
even in a modern compiler.

The variables a2, b2, and c2 in the f2() function are not initialized.
Since they're automatic variables, their initial values are garbage.
If the compiler assigns them to the same registers it used for a1, b2,
and c1 in f1(), then the garbage value are going to be whatever was
already in those variables.
 
J

Joe Pfeiffer

Roberto Waltman said:
Which reminded me of the following. (Can anybody confirm this? I can
not find the original reference.)

In the Old Days, there was an original C compiler for PDP-11 Unix.

I read that this compiler had a very simple approach for handling
register declarations. Three of the CPU registers were reserved for
this purpose. The first three variables declared as 'register' were
assigned to them in the order of declaration. Any more were ignored.

This much is true. As C spread to other platforms, this meant that
the first N register declarations were obeyed (for some
machine-specific N),and the rest ignored.

There was a hilarious sequence of benchmarking dirty tricks that
turned up on usenet sometime in the early 1980s:

Intel fan: my machine is faster than Motorola, on the basis of my
benchmark.

Motorola fan: no fair! you didn't use register variables. Now that
I've put all the variables in registers, my machine is faster.

Intel fan: no fair! the order of the variables didn't put the
most-used ones first! I reorded the variable declarations and now my
machine is faster!

I don't remember if there was another round.
The contents of these registers was preserved across function calls,
making possible to use register declarations as an alternate parameter
passing mechanism without the overhead of pushing/popping data to the
stack, and it was inevitably used in this fashion by people wanting to
squeeze more performance from the system.

Not that I've heard of. Given the level of smarts in the linker, I'd
be really surprised.
 
K

Keith Thompson

Harald van Dijk said:
Oh dear. Sorry, you're completely right, of course, and that does
result in the output you expected ("10 + 20 = 30").
[...]

I just tried something similar:
================================
#include <stdio.h>

void set_registers(void)
{
register int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x0 = 100;
x1 = 101;
x2 = 102;
x3 = 103;
x4 = 104;
x5 = 105;
x6 = 106;
x7 = 107;
x8 = 108;
x8 = 109;
}

void read_registers(void)
{
register int y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
printf("%d %d %d %d %d %d %d %d %d %d\n",
y0, y1, y2, y3, y4, y5, y6, y7, y8, y9);
}

int main(void)
{
set_registers();
read_registers();
return 0;
}
================================

On most compilers and platforms, I got garbage output. But using
Sun's C compiler on Solaris/SPARC, I got the following output:

100 101 102 103 104 105 106 107 -12788660 200

Apparently the compiler re-used the same 8 registers for the first 8
"register" variables in each function, and didn't clobber them between
the calls.

You could do the same thing using something like "static register"
variables if there were such a thing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top