register keyword

J

Jackie

Hi everyone,
Does anyone know when "register" declarations should be used and when
"register" must not be used? If possible please give examples for both
cases.
Thanks
 
E

Emmanuel Delahaye

Jackie wrote on 27/07/04 :
Hi everyone,
Does anyone know when "register" declarations should be used and when
"register" must not be used? If possible please give examples for both
cases.

Don't use 'register'. The compiler makes it for you.
 
M

Malcolm

Jackie said:
Does anyone know when "register" declarations should be used and when
"register" must not be used? If possible please give examples for both
cases.
"register" is used when you want to hint to a compiler that a variable
should be in a hardware register for fast access.
Nowadays compilers are so good at assigning variables to registers that you
can seldom achieve any speed up by using "register", and may often slow
execution down.
register also prevents the address of a variable from being taken, so if you
need to set a pointer to that variable you may not declare it "register".

examples

void foo(void)
{
register int i;
int j;
int dummy = 0;
clock_t tick;
clock_t tock;

tick = clock();
for(i=0;i<10000;i++)
dummy *= dummy;
tock = clock();

printf("Register %d\n" (int) (tock - tick));

tick = clock();
for(j=0;i<10000;j++)
dummy *= dummy;
tock = clock();

printf("vanilla %d\n", (int) tock - tick);
}

void cursorpos(int *x, int *y)
{
/* dummy position for example */
*x = 1;
*y = 2;
}

void foo(void)
{
register int x;
register int y;

/* illegal */
cursorpos(&x, &y);

printf("x %d y %d\n", x, y);
}
 
J

Jackie

Hi Malcom,
I tried the code right below this message. It doesn't prevent the variable
"i" address from being taken. I could compile and run it under gcc. (It
compiles with this warning "address of register variable `i' requested" but
nothing is prevented)
int main()
{
register int i = 0;
int j = 0;
i++;

int * p = &i;
int * q = &j;

*p = 10;
*q = 8;

printf("i = %d\n", i);
printf("j = %d\n", j);
}
OUTPUT:
i = 10
j = 8
 
A

Arthur J. O'Dwyer

I tried the code right below this message. It doesn't prevent the variable
"i" address from being taken. I could compile and run it under gcc. (It
compiles with this warning "address of register variable `i' requested" but
nothing is prevented)
register int i = 0;
int * p = &i;

Because it's annoying as hell.
Why not?
Please don't top-post.

As to your question: Your compiler is certainly allowed to produce
whatever executable program it likes, for whatever reason it likes.
It has kindly warned you that your source code is /not/ valid C,
and (in this case) it has gone ahead and produced an executable
anyway. That doesn't mean you ought to ignore the diagnostic.

The code as written /is/ incorrect; you /cannot/ take the address
of an object declared 'register'.

<OT> Try 'gcc -W -Wall -ansi -pedantic -O2'; this is the command
line I find most useful for diagnosing invalid or potentially
ambiguous C code. ('-W -Wall' is considered overkill by some
regulars here.) </OT>

HTH,
-Arthur
 
J

Jack Klein

On Tue, 27 Jul 2004 18:02:49 GMT, "Jackie"


As Malcom said, don't top post.
Hi Malcom,
I tried the code right below this message. It doesn't prevent the variable
"i" address from being taken. I could compile and run it under gcc. (It
compiles with this warning "address of register variable `i' requested" but
nothing is prevented)
int main()
{
register int i = 0;
int j = 0;
i++;

int * p = &i;
int * q = &j;

*p = 10;
*q = 8;

printf("i = %d\n", i);
printf("j = %d\n", j);
}
OUTPUT:
i = 10
j = 8

Then whatever compiled this was not a standard C compiler. It might
be a C compiler that was not invoked in standard C mode, and so it
allowed some non-standard compiler-specific extensions. Or it might
be that you compiled this with a C++ compiler, where taking the
address of a register variable happens to be legal.

But whatever the reason, you did not compile this with a standard C
compiler.
 
P

Peter Nilsson

Jack Klein said:
On Tue, 27 Jul 2004 18:02:49 GMT, "Jackie"

As Malcom said, don't top post.

[Actually, it was Arthur.]
Then whatever compiled this was not a standard C compiler. It might
be a C compiler that was not invoked in standard C mode, and so it
allowed some non-standard compiler-specific extensions.

% gcc -W -Wall -ansi -pedantic -ffloat-store jackie.c
jackie.c: In function `main':
jackie.c:7: warning: address of register variable `i' requested
jackie.c:7: warning: ISO C89 forbids mixed declarations and code
jackie.c:13: warning: implicit declaration of function `printf'
jackie.c:15: warning: control reaches end of non-void function

% a.exe
i = 10
j = 8

%

In what way did I not invoke gcc as a conforming compiler?
Or it might
be that you compiled this with a C++ compiler, where taking the
address of a register variable happens to be legal.

[But not supplying a prototype for printf isn't.]
But whatever the reason, you did not compile this with a standard C
compiler.

I think you've jumped the gun.
 
M

Malcolm

Jack Klein said:
Or it might be that you compiled this with a C++ compiler, where taking the
address of a register variable happens to be legal.
That's a little factoid I was unaware of.
 
R

Richard Bos

Then whatever compiled this was not a standard C compiler. It might
be a C compiler that was not invoked in standard C mode, and so it
allowed some non-standard compiler-specific extensions.

Why? It's a constraint violation. It requires a diagnostic. A diagnostic
was provided. Sounds conforming to me.

Richard
 
T

Thomas Matthews

Jackie said:
Hi everyone,
Does anyone know when "register" declarations should be used and when
"register" must not be used? If possible please give examples for both
cases.
Thanks

The register keyword should be used as a last resort when
optimizing a function; and it is platform dependent as to
whether it will be efficient or not. By the way, the
"register" keyword is only a hint to the compiler. The
compiler is allow to ignore your suggestion.

Given a program fragment to sum array locations:

#define ARRAY_SIZE 102400

unsigned int array[ARRAY_SIZE];

// Assume array has been filled with valid integers.
unsigned int Array_Sum(unsigned int * p_array,
unsigned int quantity)
{
unsigned int i;
unsigned int sum = 0;

for (i = 0; i < quantity; ++i)
{
sum += p_array;
}
return sum;
}

In the above function, Array_Sum, the array is
accessed one location at a time. In generic
computer theory, accessing many memory locations
at once is faster than many accesses to many
memory locations.

Here is the same function, but applying the
above idea and loop unrolling:
unsigned int Array_Sum(unsigned int * p_array,
unsigned int quantity)
{
unsigned int i;
unsigned int sum = 0;

/* declare some temporary values to use the
processors "extra" registers */
register unsigned int r1, r2, r3, r4;
#define ACCESSES_PER_LOOP 4

for (i = 0;
i + ACCESSES_PER_LOOP < quantity;
i += ACCESSES_PER_LOOP)
{
/* Read from memory into several registers */
r1 = p_array[i + 0];
r2 = p_array[i + 1];
r3 = p_array[i + 2];
r4 = p_array[i + 3];

/* Calculate sum using registers */
sum += r1;
sum += r2;
sum += r3;
sum += r4;
}

/* Sum up remaining numbers */
for (; i < quantity; ++i)
{
sum += p_array;
}
return sum;
}

Hopefully, the compiler is smart enough to recognize the
reading pattern and use specialized processor instructions.
The loop unrolling serves two purposes: 1) More data
processing instructions are exected per branch instructions;
and 2) Allows for multiple fetches from memory at one time.
Whether or not the compiler or process takes advantage of
2), depends on the compiler and the platform. This solution
works nice on an ARM7 or ARM9 processor that has a
special instruction for loading multiple registers from
memory with one instruction.

So the "register" keyword along with loop unrolling
help form an optimization pattern. A good compiler will
take the hints and generate appropriate code. If the
compiler doesn't generate the optimized code, there is
always the option of writing the code in assembly language.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

Joona I Palaste

Malcolm said:
That's a little factoid I was unaware of.

But if the compiler *does* choose to place the variable into a hardware
register, what would that address look like?
 
C

Christian Bau

Joona I Palaste said:
But if the compiler *does* choose to place the variable into a hardware
register, what would that address look like?

It doesn't have to "look like" anything, it just has to work.

For example take the code fragment

int i, j;
...
if (&i == &j) ...

The rules of the C language imply that (&i == &j) must be zero (false).
The compiler is free to place i or j or both into a hardware register,
as long as it makes sure that (&i == &j) yields a value of zero.
 
K

Keith Thompson

Joona I Palaste said:
But if the compiler *does* choose to place the variable into a hardware
register, what would that address look like?

<OT>
Most likely, if the program takes the address of a variable, the
compiler won't choose to put that variable in a register. Either
that, or it will mirror the value of the variable in a register and in
a memory location, guaranteeing that the memory location holds the
correct value whenever the address is used.
</OT>
 

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,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top