Register storage type

F

Free Willy

Hello

Say the CPU has only AL, BL, CL, DL or eight 8 bit registers, and if
want to declare 10 register variables in my code, is it possible to do
it?

Say size_of(float) is the same as size_of(int), is it possible to define
a "register float" variable? How will the register get converted between
int and float?

Thanks.
 
F

Free Willy

Kenneth said:
The "register" keyword is just a hint to the compiler, which it is free
to use or ignore as it sees fit.

OK, but will it always give a warning if you try to assign too many
register variables for the CPU (or the wrong type of variable, if this
isn't supported), or just compile it possibly with errors or undefined
behaviors at runtime?

Another question is array variables declared as register type - could the
compiler put a small array say of 3 elements into different registers and
translate array accesses to the right register?
 
A

Angel

Say the CPU has only AL, BL, CL, DL or eight 8 bit registers, and if
want to declare 10 register variables in my code, is it possible to do
it?

The"register" specifier is a hint for the compiler; the compiler
is not required to follow it. If it's not possible on a given
architecture, then of course the compiler will ignore it and treat the
variable like any other.
Say size_of(float) is the same as size_of(int), is it possible to define
a "register float" variable? How will the register get converted between
int and float?

Size or type don't matter, you can give any automatic variable the register
specifier. The compiler will assign an actual register if it is feasible
to do so. This varies per implementation.

Internally, any type of variable is represented as a number of bits,
which is the only thing a computer can work with. If the number of bits
required to represent the variable can fit in a register, the compiler
may do so. No special conversion is needed; a variable in a register is no
different from a variable in normal memory, except that you cannot have a
pointer to a register.
 
K

Keith Thompson

Free Willy said:
Say the CPU has only AL, BL, CL, DL or eight 8 bit registers, and if
want to declare 10 register variables in my code, is it possible to do
it?

Certainly, you can declare as many register variables as you like.
Say size_of(float) is the same as size_of(int), is it possible to define
a "register float" variable? How will the register get converted between
int and float?

(It's "sizeof", not "size_of".)

You can define a "register float" variable regardless of the relative
sizes of int and float. No conversion is implied. You can use the
"register" specifier for any declaration, as long as it's inside a
function (though declaring an array as "register" means you can't
do anything with it other than applying "sizeof").

The thing to remember is that "register" doesn't mean "store this
object in a CPU register". All the standard says is that

A declaration of an identifier for an object with storage-class
specifier register suggests that access to the object be as
fast as possible. The extent to which such suggestions are
effective isimplementation-defined.

and that you can't take the address of a register object, or declare
one outside a function.

The common wisdom these days is that the compiler can do a better
job of deciding what to store in a register than you're likely to,
and that declaring objects as "register" can even hurt performance
if the compiler pays attention to it. I'm actually not sure whether
this is correct in general.
 
A

Angel

OK, but will it always give a warning if you try to assign too many
register variables for the CPU (or the wrong type of variable, if this
isn't supported), or just compile it possibly with errors or undefined
behaviors at runtime?

Since it's just a hint, no warnings will be given if the compiler
cannot, or chooses not to follow it. This will not lead to errors or
undefined behaviour; the variables will simply be treated like all
others.
Another question is array variables declared as register type - could the
compiler put a small array say of 3 elements into different registers and
translate array accesses to the right register?

I might, if doing so is feasible. The language makes no guarantee
either way, it's up to the compiler to decide.
 
K

Keith Thompson

Free Willy said:
OK, but will it always give a warning if you try to assign too many
register variables for the CPU (or the wrong type of variable, if this
isn't supported), or just compile it possibly with errors or undefined
behaviors at runtime?

A compiler can warn about anything it likes, and some might give such a
warning, either by default or by the use of some command-line option.
But no such warning is required, and as far as I know most compilers
won't bother.

Declaring "too many" register variables won't cause errors or undefined
behavior. The compiler isn't disobeying the "register" specifier, since
the specifier (in spite of the name) doesn't say to store the variable
in a register.
Another question is array variables declared as register type - could the
compiler put a small array say of 3 elements into different registers and
translate array accesses to the right register?

If you declare an array variable as "register", you can't take its
address. Since array indexing is defined in terms of addresses, such an
array variable is pretty much useless.

If you declare an array variable *without* "register", the compiler can
store it in one or more registers, as long as the behavior of the
program is not affected. For example, if you take the address of one of
the elements of the array and pass it to some function, the compiler
isn't likely to be able to store it in a register, since the called
function woudnl't know how to access it.
 
S

Seebs

The common wisdom these days is that the compiler can do a better
job of deciding what to store in a register than you're likely to,
and that declaring objects as "register" can even hurt performance
if the compiler pays attention to it. I'm actually not sure whether
this is correct in general.

It can have one positive effect:

Because it guarantees that the address of a thing can't be taken, it can
in some cases allow a compiler to optimize better whether or not it puts
the object in question "in a register", just because there's no need to worry
about things modifying the object through pointers.

-s
 
K

Keith Thompson

Seebs said:
It can have one positive effect:

Because it guarantees that the address of a thing can't be taken, it can
in some cases allow a compiler to optimize better whether or not it puts
the object in question "in a register", just because there's no need to worry
about things modifying the object through pointers.

Ah, but "register" can be applied only to block-scope. Presumably
any decent optimizing compiler can already tell that a block-scope
variable's address is never taken, just by analyzing the code.
 
B

BGB

It can have one positive effect:

Because it guarantees that the address of a thing can't be taken, it can
in some cases allow a compiler to optimize better whether or not it puts
the object in question "in a register", just because there's no need to worry
about things modifying the object through pointers.

yes, but a compiler can easily enough infer that the address isn't taken.

for example:
void func()
{
int x;
...
}

if the compiler doesn't ever see an "&x" or similar in the function,
then it can generally assume that the address of 'x' is not taken.


well, except maybe if the compiler is single-pass or lacks any sort of
optimizing stages...


it is much like, there are optimizations that can be broken by the
ability to freely 'goto' here and there, but an absence of any labels or
gotos in the area can make these optimizations safe.

say:
if(0) { ... }

an absence of labels/gotos will then allow the compiler to simply omit
the code indicated by "...".

or such...
 
S

Seebs

Ah, but "register" can be applied only to block-scope. Presumably
any decent optimizing compiler can already tell that a block-scope
variable's address is never taken, just by analyzing the code.

I try not to make assumptions about whether things are "decent". The
world continues to surprise and astound me, even after all these years.

Remember: The phrase "no one would be dumb enough to..." does not come
at the beginning of any true statement.

-s
 
K

Keith Thompson

Seebs said:
I try not to make assumptions about whether things are "decent". The
world continues to surprise and astound me, even after all these years.

Remember: The phrase "no one would be dumb enough to..." does not come
at the beginning of any true statement.

Ok, but your point (that "register" can help an optimizer by telling
it that an object's address is never taken) is relevant only for a
compiler that (a) is too dumb to detect by itself that a block-scope
object's address is never taken, but (b) is smart enough to make
good use of the information.

Conceivable, but not the way I'd bet -- and I wouldn't clutter my
code with otherwise superfluous "register" specifiers to cater to
such compilers without a very good reason.
 
S

Seebs

Ok, but your point (that "register" can help an optimizer by telling
it that an object's address is never taken) is relevant only for a
compiler that (a) is too dumb to detect by itself that a block-scope
object's address is never taken, but (b) is smart enough to make
good use of the information.

Conceivable, but not the way I'd bet -- and I wouldn't clutter my
code with otherwise superfluous "register" specifiers to cater to
such compilers without a very good reason.

Yeah. The most significant effect, I think, is probably that if you
have a large code base in which there are multiple actors and some macros
and inline functions, tagging something "register" could prevent someone
from *accidentally* taking its address.

-s
 
P

Peter Nilsson

Free Willy said:
Say the CPU has only AL, BL, CL, DL or eight 8 bit registers,
and if want to declare 10 register variables in my code, is it
possible to do it?

The keyword register is a misnomer. Apart from excluding you
from taking an address, it's redundant.

On register rich CPUs (Sparc), it will be ignored. On register
poor CPUs (x86), it will be ignored. On 'middle' CPU's (68000),
it will almost certainly be ignored since modern compilers are
better at determining which variables should be allocated to
registers than programmers.

In short, register is about as useful as auto.
 
E

Eric Sosman

[...]
Another question is array variables declared as register type - could the
compiler put a small array say of 3 elements into different registers and
translate array accesses to the right register?

It is possible to define an array with `register', but the
array is pretty much useless. Since all array accesses are defined
in terms of pointer operations, and since you can't form a pointer
to a register variable, you wind up with an array you can't use!
The only operation you can do with it is apply `sizeof'.

Stepping back a second and taking a wider view, I suspect your
fascination with `register' is unhealthy, and that you should
muster all your will power to forget the keyword's existence. You
mention a CPU with only a few hardware registers, and (it seems)
you imagine you'll get greater speed by dedicating them to your
most frequently-used variables. Tell me, then: If all the registers
are busy holding the values of `w', `x', `y', `z', where will the
compiler keep the intermediate results in `x * y + w * z'?

Drop it. Just drop it, and step away from the keyboard, keeping
both hands in view. Good. Now show me the MEASUREMENTS that indicate
you need to micro-optimize. If you haven't made them, I'm giving you
a ticket and a fine for Premature Optimization. Do you feel lucky?
 
F

Free Willy

Kenneth said:
If you declare an array variable as "register", you can't take its
address. Since array indexing is defined in terms of addresses, such
an array variable is pretty much useless.

And can lead to some "interesting" errors:

...
register int foo[3];
foo[0] = 1;
...

This causes the error "'&' on register variable".

(Yes, I know _why_ it says that, but it is a bit unexpected at first
glance.)

[...]

This is interesting, I usually use g++ which compiles the code without
any warnings, but gcc throws a compile error!
 
K

Keith Thompson

Free Willy said:
Kenneth said:
Another question is array variables declared as register type - could
the compiler put a small array say of 3 elements into different
registers and translate array accesses to the right register?

If you declare an array variable as "register", you can't take its
address. Since array indexing is defined in terms of addresses, such
an array variable is pretty much useless.

And can lead to some "interesting" errors:

...
register int foo[3];
foo[0] = 1;
...

This causes the error "'&' on register variable".

(Yes, I know _why_ it says that, but it is a bit unexpected at first
glance.)

[...]

This is interesting, I usually use g++ which compiles the code without
any warnings, but gcc throws a compile error!

Always remember that C and C++ are two different languages. The C++
semantics for "register" differ from the C semantics.

<OT>
C++ 2003 7.1.1p3:
A register specifier has the same semantics as an auto specifier
together with a hint to the implementation that the object so
declared will be heavily used. [Note: the hint can be ignored
and in most implementations it will be ignored if the address
of the object is taken. —end note]
</OT>
 
K

Kenny McCormack

Keith Thompson said:
Always remember that C and C++ are two different languages. The C++

Perl 3 and Perl 4 and Perl 5 are all different languages, too.

So what?

(Yes, there is a point in all of this, but I'm too lazy to write it all out
right now. If you're smart, you'll get it...)

--
One of the best lines I've heard lately:

Obama could cure cancer tomorrow, and the Republicans would be
complaining that he had ruined the pharmaceutical business.

(Heard on Stephanie Miller = but the sad thing is that there is an awful lot
of direct truth in it. We've constructed an economy in which eliminating
cancer would be a horrible disaster. There are many other such examples.)
 
D

Dr Nick

Perl 3 and Perl 4 and Perl 5 are all different languages, too.

So what?

(Yes, there is a point in all of this, but I'm too lazy to write it all out
right now. If you're smart, you'll get it...)

Just before I'll pop you back in my killfile, I'll ask you to explain
the point. Because this wasn't a gratuitous pop at C/C++ it was an
important explanation of why something worked in one and not in the
other, and not because of a new feature, but because the semantics of a
keyword have subtly changed.

I have to say, for a troll you have astonishing patience, but surely
there's something more productive you could do with the hours and hours
you spend on this.
 
F

Free Willy

Keith said:
Free Willy said:
Kenneth said:
On 5/12/2011 5:27 PM, Keith Thompson wrote:
[...]
Another question is array variables declared as register type -
could the compiler put a small array say of 3 elements into
different registers and translate array accesses to the right
register?

If you declare an array variable as "register", you can't take its
address. Since array indexing is defined in terms of addresses, such
an array variable is pretty much useless.

And can lead to some "interesting" errors:

...
register int foo[3];
foo[0] = 1;
...

This causes the error "'&' on register variable".

(Yes, I know _why_ it says that, but it is a bit unexpected at first
glance.)

[...]

This is interesting, I usually use g++ which compiles the code without
any warnings, but gcc throws a compile error!

Always remember that C and C++ are two different languages. The C++
semantics for "register" differ from the C semantics.

<OT>
C++ 2003 7.1.1p3:
A register specifier has the same semantics as an auto specifier
together with a hint to the implementation that the object so
declared will be heavily used. [Note: the hint can be ignored and in
most implementations it will be ignored if the address of the object
is taken. —end note]
</OT>

That's interesting, although I don't think it really explains it - I
normally use g++ in C mode because it gives some extra type checking, eg
prevents implicit typecasting of pointers.

Personally I think the C++ way is better than the C way - it avoids
problems if you try to assign more register variables than the machine
has registers available, effectively in C++ it sounds like the compiler
can "fall back" to discarding the register specification and treating it
like a normal stack variable should there be no register available.

I use the register keyword to tell the compiler that a variable is used a
lot eg as a loop index. What I "really want" is for the compiler to
optimize access to that variable - putting it in a register is only a
means to an end!
 
I

Ian Collins

Keith said:
Free Willy said:
This is interesting, I usually use g++ which compiles the code without
any warnings, but gcc throws a compile error!

Always remember that C and C++ are two different languages. The C++
semantics for "register" differ from the C semantics.

<OT>
C++ 2003 7.1.1p3:
A register specifier has the same semantics as an auto specifier
together with a hint to the implementation that the object so
declared will be heavily used. [Note: the hint can be ignored and in
most implementations it will be ignored if the address of the object
is taken. —end note]
</OT>

That's interesting, although I don't think it really explains it - I
normally use g++ in C mode because it gives some extra type checking, eg
prevents implicit typecasting of pointers.

Personally I think the C++ way is better than the C way - it avoids
problems if you try to assign more register variables than the machine
has registers available, effectively in C++ it sounds like the compiler
can "fall back" to discarding the register specification and treating it
like a normal stack variable should there be no register available.

The easiest solution is to not use the register keyword. It's an
anachronism with modern compilers.
I use the register keyword to tell the compiler that a variable is used a
lot eg as a loop index. What I "really want" is for the compiler to
optimize access to that variable - putting it in a register is only a
means to an end!

The compiler can perform the required optimisations on its own!
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top