Register variables doubt

V

Vashna

But then that raises even more questions! Suppose I define register
variables a,b,c,d,e and the CPU has only 4 registers. In this case, if
what you say is true, the compiler will put one of these variables into
a memory location. This means we can take the address of it with the &
function. So is it the last defined variable that will be put into
memory? And if so, if we compile the program on a machine with 6
registers and we've relied on using &e somewhere, this will lead to a
runtime error...

This seems like a worrying ambiguous point in the language!

Thanks.
 
S

santosh

Vashna wrote:
[please don't top post; fixed here]
But then that raises even more questions! Suppose I define register
variables a,b,c,d,e and the CPU has only 4 registers. In this case, if
what you say is true, the compiler will put one of these variables
into a memory location.

Don't assume that it'll put only _one_ of 'a', 'b', 'c' or 'd' into
memory. It could be anywhere between one to all of them. You cannot
determine portabily which.
This means we can take the address of it with
the & function.

No. The address of _all_ objects qualified with register cannot be
taken. This follows from the rule that register is merely a hint and
may or may not be actually honoured. Since it's impossible for a
Standard C program to determine which of it's register qualified
objects have *actually* been placed into registers, the Standard
prohibits all of them from having an address.
So is it the last defined variable that will be put
into memory? And if so, if we compile the program on a machine with 6
registers and we've relied on using &e somewhere, this will lead to a
runtime error...

This seems like a worrying ambiguous point in the language!

No. All objects qualified with register do not have addresses.
 
K

Keith Thompson

santosh said:
Vashna wrote: [...]
But then that raises even more questions! Suppose I define register
variables a,b,c,d,e and the CPU has only 4 registers. In this case, if
what you say is true, the compiler will put one of these variables
into a memory location.

Don't assume that it'll put only _one_ of 'a', 'b', 'c' or 'd' into
memory. It could be anywhere between one to all of them. You cannot
determine portabily which.
This means we can take the address of it with
the & function.

No. The address of _all_ objects qualified with register cannot be
taken. This follows from the rule that register is merely a hint and
may or may not be actually honoured. Since it's impossible for a
Standard C program to determine which of it's register qualified
objects have *actually* been placed into registers, the Standard
prohibits all of them from having an address.

Actually, it follows from the explicit statement in the standard that
the unary "&" shall not be applied to an object declared with the
register storage-class specifier (C99 6.5.3.2p1).
No. All objects qualified with register do not have addresses.

That last sentence is ambiguous; what you mean, I think, is that no
objects qualfied with register have addresses. (It could also be read
as "Not all objects qualified with register have addresses", which
leaves open the possibility that some of them do.)

But the actual rule is that a register-qualified object's address
cannot be computed. It might have an address; you just can't get it.
(On the other hand, as far as the visible semantics are concerned, it
really doesn't have an address.)

And an object without register qualification might still be stored in
a CPU register, and not have an address. Even if the program applies
"&" to it, the compiler just has to guarantee that it exists at that
address when it's used. For example:

int x = 42;
printf("Address of x is %p\n", (void*)&x);
/*
* Followed by a bunch of code that refers to the value of x, but
* not to its address.
*/

The compiler might decide to store x in a register after the printf
statement.

The "register" keyword does just two things.

1. It hints to the compiler that accesses to the object should be fast
(and maybe putting it in a register is a good way to do that).

2. It forbids taking the address of the object.
 
V

Vashna

Vashna wrote:
[please don't top post; fixed here]
But then that raises even more questions! Suppose I define register
variables a,b,c,d,e and the CPU has only 4 registers. In this case, if
what you say is true, the compiler will put one of these variables
into a memory location.

Don't assume that it'll put only _one_ of 'a', 'b', 'c' or 'd' into
memory. It could be anywhere between one to all of them. You cannot
determine portabily which.
This means we can take the address of it with
the & function.

No. The address of _all_ objects qualified with register cannot be
taken. This follows from the rule that register is merely a hint and
may or may not be actually honoured. Since it's impossible for a
Standard C program to determine which of it's register qualified
objects have *actually* been placed into registers, the Standard
prohibits all of them from having an address.

Are you reaaly sure that's right? What about C programs used in
device drivers or lowlevel kernel work that really need to know when a
variable is going to be stored in a register?
 
S

santosh

Vashna said:
Vashna wrote:
[please don't top post; fixed here]
On 6 Oct 2007 at 14:30, santosh wrote:
Vashna wrote:

Thanks for all the answers, I feel like I understand it much
better now.

The only doubt I still have is: what if in a single function we
define more register variables than there are registers in the
CPU? Will we get a compile time error, or just unpredictable
behavior at runtime?

Neither. The implementation will simply ignore one or more or all
of your register requests.

But then that raises even more questions! Suppose I define register
variables a,b,c,d,e and the CPU has only 4 registers. In this case,
if what you say is true, the compiler will put one of these
variables into a memory location.

Don't assume that it'll put only _one_ of 'a', 'b', 'c' or 'd' into
memory. It could be anywhere between one to all of them. You cannot
determine portabily which.
This means we can take the address of it with
the & function.

No. The address of _all_ objects qualified with register cannot be
taken. This follows from the rule that register is merely a hint and
may or may not be actually honoured. Since it's impossible for a
Standard C program to determine which of it's register qualified
objects have *actually* been placed into registers, the Standard
prohibits all of them from having an address.

Are you reaaly sure that's right?
Yes.

What about C programs used in device drivers or lowlevel kernel work
that really need to know when a variable is going to be stored in a
register?

Even in most cases of system programming it's not necessary to know
which objects are currently in registers. The whole purpose of a
high-level language like C is to free the programmer of such a burden.

When a register _must_ be used the only options are to drop down to
assembler or inline assembler, if the latter is supported by the
implementation.
 
I

Ian Collins

CBFalconer said:
santosh wrote:
.... snip ...

Rather hard unless you simultaneously restrict C to run on only one
architecture. :)
The C++ standard for the asm declaration is simply

asm ( string-literal ) ;

The meaning is implementation defined.

The informative annex J.5.10 in C99 says pretty much the same.
 
C

Chris Torek

C++ defines the asm keyword and its syntax:

asm ( string-literal ) ;

but leaves its semantics entirely implementation-defined.

I'm not convinced that this is useful. ...

It seems to me to be as useful as the non-Standard-ized pragmas.
Any program that uses ``asm'' is inherently non-portable, and must
be modified if it's to be ported to another platform. I don't see
how standardizing part of the syntax aids portability (or anything else).

It mostly avoids getting dozens of incompatible syntaxes for
"common extensions". The situation today in C is that we have
things like:

#ifdef USING_GCC
__asm__("xyz %1,%0" : "=r"(result) : "r"(input));
#endif
#ifdef USING_FOO_C
_Asm {
xyz $t0,$r3
}
#endif
#ifdef USING_BAR_C
asm xyz r3,t0
#endif
/* ... */

If they all had reasonably-compatible syntax, we might at least have:

#ifdef USING_GCC
# define INSTRUCTION "xyz %1, %0" : "=r"(result) : "r"(input)
#endif
#ifdef USING_FOO_C
# define INSTRUCTION "xyz $t0,$r3"
#endif
#ifdef USING_BAR_C
# define INSTRUCTION "xyz r3,t0"
#endif
#ifndef INSTRUCTION
# error do not know how to do inline assembly with this compiler
#endif
asm(INSTRUCTION);

which seems to be a *slight* improvement, anyway.
 
C

CBFalconer

Chris said:
.... snip ...

If they all had reasonably-compatible syntax, we might at least have:

#ifdef USING_GCC
# define INSTRUCTION "xyz %1, %0" : "=r"(result) : "r"(input)
#endif
#ifdef USING_FOO_C
# define INSTRUCTION "xyz $t0,$r3"
#endif
#ifdef USING_BAR_C
# define INSTRUCTION "xyz r3,t0"
#endif
#ifndef INSTRUCTION
# error do not know how to do inline assembly with this compiler
#endif
asm(INSTRUCTION);

which seems to be a *slight* improvement, anyway.

Seems to me it would be easier to write appropriate source files
for each system, and simply arrange for the make file to
assemble/compile the appropriate one. After that the linker can
take care of things.
 
E

Eric Sosman

Richard said:
I don't care what the standard says. It is unpredictable behaviour. Not
"undefined". It is unpredictable since you have NO idea if or how a
register is assigned. [...]

I'm not sure, but are you asking for the compiler to
emit an error message if it doesn't honor your `register'
keyword?

(And then there's the slippery question of just what
it means to "honor" the keyword ...)
 
K

Kenneth Brody

Richard said:
I don't care what the standard says. It is unpredictable behaviour. Not
"undefined". It is unpredictable since you have NO idea if or how a
register is assigned. You correctly point out however, that one CAN go
to assembler if the glove really doesn't fit.
[...]

I'm not sure I agree with you on this one. If the compiler did its
job, there will be no discernable difference in behavior whether the
variable is placed in a register or not, aside from a possible change
in speed of execution. (And, just to be clear, if the compiler were
forced to heed your "demand" that the variable be placed in a register,
that version might actually run slower than if the compiler were
allowed to pick which variables went in registers.)

If there is no discernable difference in behavior, where exactly does
this "unpredictable" part come into play?

And, if not placing a register variable into a register causes
"unpredictable" behavior, can't the same be said about placing a
non-register variable into a register?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
D

David Thompson

C++ defines the asm keyword and its syntax:

asm ( string-literal ) ;

but leaves its semantics entirely implementation-defined.

I'm not convinced that this is useful. Any program that uses ``asm''
is inherently non-portable, and must be modified if it's to be ported
to another platform. I don't see how standardizing part of the syntax
aids portability (or anything else).

It allows other tools to correctly parse (the C part of) the code
without needing to know the asm quirks for particular compiler(s).

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
K

Keith Thompson

David Thompson said:
It allows other tools to correctly parse (the C part of) the code
without needing to know the asm quirks for particular compiler(s).

That's an *excellent* point.

In some circumstances, it might also be useful to write

#define asm(str) /* something-or-other */

though of course it's subject to abuse.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top