[comp.lang.c] Novice question.

donn@brat.UUCP (Donn Pedro) (11/02/90)

A question for you that know, because I dont.


I understand that the following is a pointer.

> 	char *s;

But what is this doing?
Why the two "*". 

> 	STRING **s_array;

Please e-mail.

I couldn't find it in K&R.  


      Donn F Pedro ....................a.k.a. uunet!nwnexus!mcgp1!brat!donn
         else:  {the known world}!uunet!nwnexus!mcgp1!brat!donn 

morse@currituck.cs.unc.edu (Bryan Morse) (11/03/90)

In article <336@brat.UUCP> donn@brat.UUCP (Donn Pedro) writes:
>A question for you that know, because I dont.
>
>
>I understand that the following is a pointer.
>
>> 	char *s;
>
>But what is this doing?
>Why the two "*". 
>
>> 	STRING **s_array;
>
>Please e-mail.

I'm posting my reply since the mail I sent you bounced.  Besides, maybe
someone else wants to know (and if someone doesn't, my apologies).

First, the real way to read C declarations.

Any statement of the form

        type <list of expressions>

says that all expressions in the list are of the specified type.

Thus, the statement

        char *s;

does not (repeat, does *not*) say that s is a pointer to a char.  What
it says is that *s is a char.  It may seem the same (and in reality is)
but it's important to make the distinction.  That's why you can say

        char c, *s;

and declare both a char and a pointer to one.  A very common mistake is to
say "hmm, I want to declare a few char pointers" and type

        char *  s,t;
        ------  ---
        type    list of variables

and this is WRONG!  Be very careful to think in terms of this C style
instead of the Pascal style where you specify the type (including pointers)
and a list of variables.  Does this make sense?

Having said this, let's get to your question:

        STRING **s;

says that **s is of type STRING.  Since *s is what s points to and **s is
what *s points to (you can chain dereferences in C like what--similar to
p^^ in Pascal if you've every seen it) that means that s is a pointer to
a pointer to a STRING.  Make sense?

Seriously, once you learn this simple rule of how to read C declarations,
you can understand even the most convoluted declarations.

Hope this helps..

Bryan Morse                University of North Carolina at Chapel Hill
morse@cs.unc.edu           Department of Computer Science

jmwojtal@vela.acs.oakland.edu (Wojo) (11/13/90)

What exactly are the reasons "register" and "extrn" are used to declare
values.  I see register alot in some of the programs and I don't know why
they do it.  Is it just good practice or what.



-- 
************************************************************************
Jeff Wojtalewicz (Wojo)  jmwojtal@vela.acs.oakland.edu
Oakland University		      Start Hacking
************************************************************************

gordon@osiris.cso.uiuc.edu (John Gordon) (11/14/90)

jmwojtal@vela.acs.oakland.edu (Wojo) writes:

>What exactly are the reasons "register" and "extrn" are used to declare
>values.  I see register alot in some of the programs and I don't know why
>they do it.  Is it just good practice or what.

	"register" means that the variable will be stored in a portion of
memory that can be accessed significantly faster than normal.  Useful for 
loop counters, among other things.  There are a limited number of registers
available.  MS-DOS machines, for example, have around 16 (I think).

	"extern" means that the variable is global, and was declared in a
separate .c file.  If your program occupies only 1 file, you will never
use this.


---
John Gordon
Internet: gordon@osiris.cso.uiuc.edu        #include <disclaimer.h>
          gordon@cerl.cecer.army.mil       #include <clever_saying.h>
GEnie:    j.gordon14                  

kdq@demott.COM (Kevin D. Quitt) (11/14/90)

In article <1990Nov14.010511.7241@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>	"register" means that the variable will be stored in a portion of
>memory that can be accessed significantly faster than normal.  Useful for 
>loop counters, among other things.  There are a limited number of registers
>available.  MS-DOS machines, for example, have around 16 (I think).

    Would you believe 2 registers for C (SI and DI)?


-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

zhou@brazil.psych.purdue.edu (Albert Zhou) (11/14/90)

   Registers reside within CPU and certainly are accessed much more efficiently,but I just cannot help thinking how silly we are to be content with such a
limited number of registers. When CPU was originally designed decades ago,
it was very costly to increase the size of CPU. Today, we still stick to
a single small-size CPU with no reason. It's high time for a revolution.
How many people can envision a microcomputer with thousands of big CPU, each
having thousands of registers?

mneerach@iiic.ethz.ch (Matthias Ulrich Neeracher) (11/14/90)

In article <3838@vela.acs.oakland.edu> jmwojtal@vela.acs.oakland.edu (Wojo) writes:
>What exactly are the reasons "register" and "extrn" are used to declare
>values.  I see register alot in some of the programs and I don't know why
>they do it.  Is it just good practice or what.

"extern" essentially tells the compiler that this variable is defined 
elsewhere.

"register" is a hint to the compiler that this variable will be used a lot
and that the compiler should try to keep it in a processor register. This
hint was introduced in a time when programmers were smart and compilers were
stupid. Today, the opposite is true :-), so some compilers ignore "register"
hints completely and allocate registers as they see fit.

Matthias

-----
Matthias Neeracher                                   mneerach@iiic.ethz.ch
   "These days, though, you have to be pretty technical before you can 
    even aspire to crudeness." -- William Gibson, _Johnny Mnemonic_

epames@eos.ericsson.se (Michael Salmon) (11/14/90)

In article <1990Nov14.010511.7241@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>
>	"register" means that the variable *will* be stored in a portion of
>memory that can be accessed significantly faster than normal.

I don't wish to sound pedantic but register is intended as a hint to the
compiler that the variable should be stored in some fast access but the
compiler need not do so. Many of the early C compiler I used ignored this
and if I remember correctly the Zortech compiler thinks it can determine
which variables to place in registers better than the programmer.

Michael Salmon
L.M.Ericsson
Stockholm

dylan@ibmpcug.co.uk (Matthew Farwell) (11/14/90)

In article <1990Nov14.010511.7241@ux1.cso.uiuc.edu> gordon@osiris.cso.uiuc.edu (John Gordon) writes:
>jmwojtal@vela.acs.oakland.edu (Wojo) writes:
>>What exactly are the reasons "register" and "extrn" are used to declare
>>values.  I see register alot in some of the programs and I don't know why
>>they do it.  Is it just good practice or what.
>
>	"register" means that the variable will be stored in a portion of
                                           ^^^^
>memory that can be accessed significantly faster than normal.  Useful for 
>loop counters, among other things.  There are a limited number of registers
>available.  MS-DOS machines, for example, have around 16 (I think).

Surely this should be 'might be stored in a high speed register', depending
on whether the compiler wants to put it there, is able to put it there,
whether there is an s in the day today, etc. etc. I always thought that
register was just advice to the compiler, which its free to ignore if it
wants to or is unable to fulfil the request.

Dylan.
-- 
Matthew J Farwell                 | Email: dylan@ibmpcug.co.uk
The IBM PC User Group, PO Box 360,|        ...!uunet!ukc!ibmpcug!dylan
Harrow HA1 4LQ England            | CONNECT - Usenet Access in the UK!!
Phone: +44 81-863-1191            | Sun? Don't they make coffee machines?

longshot@monkey.ecn.purdue.edu (The Knight Guard) (11/14/90)

>	"extern" means that the variable is global, and was declared in a
>separate .c file.  If your program occupies only 1 file, you will never
>use this.
>
>John Gordon

	Not true here...  Our cc seems to require that all functions/procedures
  be defined before the main block.  The way around this is to extern all 
  functions before main...  Dunno if this is just our compiler, anyone else
  seen this?  Any ideas of why?

--
--- 
							***
    To be "remembered with an affection  	       **
    and veneration that shall surge high              *

gwyn@smoke.brl.mil (Doug Gwyn) (11/14/90)

In article <3838@vela.acs.oakland.edu> jmwojtal@vela.acs.oakland.edu (Wojo) writes:
>What exactly are the reasons "register" and "extrn" are used to declare
>values.  I see register alot in some of the programs and I don't know why
>they do it.  Is it just good practice or what.

"extern" is important in that it makes a declaration a reference to
something defined elsewhere; objects declared without extern at "file
scope" (outside of any function) constitute definitions, and there may
be but one definition per object among ALL the "translation units"
(source files, or corresponding object modules) constituting a complete
program.

"register" is just an efficiency hint to the compiler, requesting that
the object be assigned to "fast" storage such as a machine register.
Many modern compilers just ignore explicit "register" requests and
allocate storage as they deem fit.  My suggestion is to not use
"register" except when you've already tried everything else to speed
up the code and still need a smidgen more speed.

Undoubtedly these are explained in Kernighan & Ritchie's "The C
Programming Language" (either edition).

heim@vms.macc.wisc.edu (JOHN HEIM ) (11/15/90)

Didn't the ANSI committee say that "register" is a *suggestion* to the 
compiler that the varible be stored in a register for faster access?  
I seem to remember reading something about that.  It may be that that 
I got it from either the Turbo C or MSC 5.1 manual though.

At any rate, I *think* that if you're working in TC or MSC you'd 
probably be better off letting the optimizer decide how to use the 
registers.  True?

------------------------------------------------------------------------------
John G. Heim                                   Internet: heim@macc.wisc.edu
UW - Madison Academic Computing Center         Phone:    608-262-9887
1210 W. Dayton St.                             Fax:      608-262-4679
Madison, WI., 53706                            CIS:      71570,3712

kaleb@thyme.jpl.nasa.gov (Kaleb Keithley ) (11/15/90)

In article <11476@j.cc.purdue.edu> zhou@brazil.psych.purdue.edu (Albert Zhou) writes:
>
>How many people can envision a microcomputer with thousands of big CPU, each
>having thousands of registers?

Yeah, it's called memory; but it's not as efficient as having the registers
in the CPU.  Or you could put a 128k fast static column RAM cache, that'd
give you 32768 general purpose registers if you want to go to the trouble
of trying to defeat the cache controller.

Let's see, according to the Intel 486 Reference, the 486 has sixteen 
registers; eight general purpose (EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI)
six segment registers (CS, SS, DS, ES, FS, GS), and two status and control
registers (EFLAGS, EIP.)  It also has eight floating point registers
R0..R7) and three FPU status and control registers.  We'll ignore the
"error pointers" for this discussion.  The reference also states the 
the 486 has 1,000,000 transisters; with 27 registers, that's over 37,000 
transistors per register.  No flames about transistor count on alternative 
architectures please, I know, for instance, that sparc has about 18,000
transistors with something like 16 general purpose registers; don't
forget to add the transistors in the FPU.

So, 1000 registers * 37,000 transistors per register = 37,000,000 transistors.
Any solder sniffers out there want to debug a 37,000,000 transister CPU. :-)

1000 registers, and to think I used to work on a 6502, with only three
8-bit registers, and two of them were index registers.  I thought I was in 
heaven when I got six on the 8086/8088.

Not sure what any of this has to do with comp.lang.c.  Thanks for listening.

-- 
Kaleb Keithley                      Jet Propulsion Labs
kaleb@thyme.jpl.nasa.gov

I don't watch Twin Peaks; I just come to work.

manning@nntp-server.caltech.edu (Evan Marshall Manning) (11/15/90)

dylan@ibmpcug.co.uk (Matthew Farwell) writes:

>Surely this should be 'might be stored in a high speed register', depending
>on whether the compiler wants to put it there, is able to put it there,
>whether there is an s in the day today, etc. etc. I always thought that
>register was just advice to the compiler, which its free to ignore if it
>wants to or is unable to fulfil the request.

How about #pragma REGISTER_BINDING to tell the compiler you're serious?
Any compiler writers listening?

***************************************************************************
Your eyes are weary from staring at the CRT for so | Evan M. Manning
long.  You feel sleepy.  Notice how restful it is  |      is
to watch the cursor blink.  Close your eyes.  The  |manning@gap.cco.caltech.edu
opinions stated above are yours.  You cannot       | manning@mars.jpl.nasa.gov
imagine why you ever felt otherwise.               | gleeper@tybalt.caltech.edu

gkt@iitmax.IIT.EDU (George Thiruvathukal) (11/15/90)

In article <14624@neptune.inf.ethz.ch>, mneerach@iiic.ethz.ch (Matthias Ulrich Neeracher) writes:
> "extern" essentially tells the compiler that this variable is defined 
> elsewhere.

It is truly unfortunate the "extern" keyword exists in C.  Let us examine the
following code fragment which allocates a vector of a size which is unknown
until function xyzpdq is encoded.

extern int TempCount;

void xyzpdq()
{
   void **temporaries = (void **)calloc(TempCount,sizeof(void *));

   /* code */

   free(temporaries);
}

/* resolution of TempCount in same compilation unit */
int TempCount = 5;

Although one might not opt to allocate temporary variables in exactly the above
fashion, it is easier than backpatching the code.  It manifests a usage of 
extern within the same compilation unit as the external reference.

George Thiruvathukal
gkt@iitmax.iit.edu

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (11/15/90)

I've been waiting to see if someone would say this, but if they have
I've missed it.

The only fixed guaranteed interpretation of 'register' in C has been
that it is identical to 'auto' _except_ that when you say 'register'
*you* are promising never ever to take the address of that variable.
It's rather like 'const'; it's a way for *you* to make promises *to*
the compiler, which the compiler may but need not exploit.

Even if you have a compiler which does a superb job of register allocation
when left to itself and a lousy job when you use 'register', it may be
worth using 'register' as a debugging aid from time to time.

-- 
The problem about real life is that moving one's knight to QB3
may always be replied to with a lob across the net.  --Alasdair Macintyre.

henry@zoo.toronto.edu (Henry Spencer) (11/16/90)

In article <11476@j.cc.purdue.edu> zhou@brazil.psych.purdue.edu (Albert Zhou) writes:
>... I just cannot help thinking how silly we are to be content with such a
>limited number of registers...

Well, some of us aren't silly.  My favorite CPU has 192 registers, give
or take a few.  (It's the AMD 29000, in case anyone is curious.)  The
silly people are the ones who blindly buy PC compatibles.
-- 
"I don't *want* to be normal!"         | Henry Spencer at U of Toronto Zoology
"Not to worry."                        |  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (11/16/90)

In article <27700@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
-In article <4524@iitmax.IIT.EDU> gkt@iitmax.IIT.EDU (George Thiruvathukal)
-writes:
->extern int TempCount;
-	... code using TempCount ...
->/* resolution of TempCount in same compilation unit */
->int TempCount = 5;
-ANSI C has made this form illegal, and requires compilers to handle
-this form instead:
-	int TempCount;	/*T*/
-	... code using TempCount ...
-	int TempCount = 5;
-The line marked /*T*/ is called a `tenative definition' in X3.159-1989-ese.

While tentative definitions must be supported, I don't recall anything
that would make the original example not strictly conforming.

zvs@bby.oz.au (Zev Sero) (11/16/90)

gkt>    void **temporaries = (void **)calloc(TempCount,sizeof(void *));

Just a silly question---is there a reason that you are using calloc
instead of malloc?  Why waste whole nanoseconds stuffing zero bits
into all that memory?  I understand the use of calloc with integers,
as an easy way of initialising them all to zero (if you need to test
them at some future stage), but what good is it with pointers?

timr@gssc.UUCP (Tim Roberts) (11/16/90)

Kaleb Keithley writes:
>Albert Zhou writes:

>>How many people can envision a microcomputer with thousands of big CPU, each
>>having thousands of registers?

>Let's see, according to the Intel 486 Reference, the 486 has sixteen 
>registers; eight general purpose (EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI)

Note:  the phrase "Intel x86 General Purpose Register" is an oxymoron.

timr@gssc.gss.com	Tim N Roberts, CCP	Graphic Software Systems

I think Lotus should come out with a PS/1 spreadsheet.  
They could call it 0-1-2.
-- 
timr@gssc.gss.com	Tim N Roberts, CCP	Graphic Software Systems

I think Lotus should come out with a PS/1 spreadsheet.  
They could call it 0-1-2.

gkt@iitmax.IIT.EDU (George Thiruvathukal) (11/16/90)

In article <27700@mimsy.umd.edu>, chris@mimsy.umd.edu (Chris Torek) writes:
> In article <4524@iitmax.IIT.EDU> gkt@iitmax.IIT.EDU (George Thiruvathukal)
> writes:
> >extern int TempCount;
> 	... code using TempCount ...
> >/* resolution of TempCount in same compilation unit */
> >int TempCount = 5;
> 
> ANSI C has made this form illegal, and requires compilers to handle
> this form instead:
> 
> 	int TempCount;	/*T*/
> 	... code using TempCount ...
> 	int TempCount = 5;
> 
> The line marked /*T*/ is called a `tenative definition' in X3.159-1989-ese.
> -- 
> In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
> Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

It is really appalling what can happen when standards groups get their dirty
paws on something.  I was under the impression that Brian Kernighan and Dennis
Ritchie designed the C language.  According to the designers of C, an external
reference is one which occurs "exactly once" and "outside any function."  The
form presented above for "tentative definition" is an absolutely absurd and
obscure feature for the insinuation of a forward (or external reference).
Congratuations to ANSI on a job well done.

I would like to make a small point: an example of external references which 
are resolved in the same unit of compilation is presented on page 32.  Thanks
to the ANSI certified confusion, individuals who program in C who once used the
"extern" as a self-documenting reference to a global variable within a function
will have no facility for such a purpose.  Clearly, tentative definition does
not appear to be a well-conceived feature (as explained by Chris Torek) and 
would certainly suggest different semantics for external references than the
ones defined on page 31 of K&R.

George Thiruvathukal
gkt@iitmax.iit.edu

gwyn@smoke.brl.mil (Doug Gwyn) (11/16/90)

In article <4525@iitmax.IIT.EDU> gkt@iitmax.IIT.EDU (George Thiruvathukal) writes:
>It is really appalling what can happen when standards groups get their dirty
>paws on something.  I was under the impression that Brian Kernighan and Dennis
>Ritchie designed the C language.  According to the designers of C, an external
>reference is one which occurs "exactly once" and "outside any function."  The
>form presented above for "tentative definition" is an absolutely absurd and
>obscure feature for the insinuation of a forward (or external reference).

It's even more appalling that people will form an opinion without solid
evidence to back it up.  Chris erred in saying that patently correct use
of external linkage was "illegal" according to the C standard.  While
the concept of tentative definition is part of the standard, it was also
inherent in the operation of many existing C compilers, including UNIX
versions.  Thus it has been formalized to work in pretty much the way
that existing implementations were intending all along.  However, the
notion of tentative definition is not one that will be encountered often
in practical programming by people who follow the guidelines of K&R (1st
edition), and definitely the K&R (1st edition) notion of external linkage
was upheld even more strongly by the standard than in actual UNIX C
implementations.

Brian didn't design or implement C, so far as I have ever heard.  That
was originally Dennis's work.  He has in fact publicly praised X3J11's
work on more than one occasion, so your thesis that the language was
damaged by the standards group's "dirty paws" seems rather weak.

jkeane@titan.uucp (Jim Keane -- Software) (11/16/90)

In article <11476@j.cc.purdue.edu> zhou@brazil.psych.purdue.edu (Albert Zhou) writes:
>
>   Registers reside within CPU and certainly are accessed much more efficiently,but I just cannot help thinking how silly we are to be content with such a
>limited number of registers. When CPU was originally designed decades ago,
>it was very costly to increase the size of CPU. Today, we still stick to
>a single small-size CPU with no reason. It's high time for a revolution.
>How many people can envision a microcomputer with thousands of big CPU, each
>having thousands of registers?

Have you ever heard of the Harvard Architecture?

yedinak@motcid.UUCP (Mark A. Yedinak) (11/17/90)

longshot@monkey.ecn.purdue.edu (The Knight Guard) writes:

:>	"extern" means that the variable is global, and was declared in a
:>separate .c file.  If your program occupies only 1 file, you will never
:>use this.
:>
:>John Gordon

:	Not true here...  Our cc seems to require that all functions/procedures
:  be defined before the main block.  The way around this is to extern all 
:  functions before main...  Dunno if this is just our compiler, anyone else
:  seen this?  Any ideas of why?

Sounds like Pascal to me. :) Seriously though, this sounds like this is just
your compiler. I have never seen this on any of the half dozen or so compilers I
have used.

-- 
Mark A. Yedinak - uunet!motcid!yedinak 		*  "Don't take life too
Motorola - General Systems Sector		*   seriously, you will
3205 Wilke Road, Arlington Heights, IL 60004	*   never get out of it
708-632-2874  (I said it, not the big M)	*         ALIVE!"

mclaren (Gavin McLaren) (11/17/90)

In article <1990Nov16.145700.8078@titan.uucp> jkeane@titan.uucp (Jim Keane -- Software) writes:
>In article <11476@j.cc.purdue.edu> zhou@brazil.psych.purdue.edu (Albert Zhou) writes:
>>How many people can envision a microcomputer with thousands of big CPU, each
>>having thousands of registers?
>
>Have you ever heard of the Harvard Architecture?

Yes, but what does this have to do with many registers? I thought
(flames cheerfully accepted if I am wrong) that the Harvard architecture's
main attribute was seperate data and instruction streams, not a large number of
registers.  Indeed, the Motorola 88000 is promoted as a Harvard architecture
part, and it has only 32 general purpose registers.

In any case, further discussion of this topic should perhaps be moved to
a more suitable newsgroup (comp.arch?).

chris@mimsy.umd.edu (Chris Torek) (11/17/90)

In article <27700@mimsy.umd.edu> I wrote:
>ANSI C has made [extern + local declaration] illegal ...

This is incorrect; `extern int foo; int foo = 5;' is legal.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

eager@ringworld.Eng.Sun.COM (Michael J. Eager) (11/21/90)

In article <4525@iitmax.IIT.EDU> gkt@iitmax.IIT.EDU (George Thiruvathukal) writes:
>It is really appalling what can happen when standards groups get their dirty
>paws on something.  I was under the impression that Brian Kernighan and Dennis
>Ritchie designed the C language.  According to the designers of C, an external
>reference is one which occurs "exactly once" and "outside any function."  The
>form presented above for "tentative definition" is an absolutely absurd and
>obscure feature for the insinuation of a forward (or external reference).
>Congratuations to ANSI on a job well done.
>
>I would like to make a small point: an example of external references which 
>are resolved in the same unit of compilation is presented on page 32.  Thanks
>to the ANSI certified confusion, individuals who program in C who once used the
>"extern" as a self-documenting reference to a global variable within a function
>will have no facility for such a purpose.  Clearly, tentative definition does
>not appear to be a well-conceived feature (as explained by Chris Torek) and 
>would certainly suggest different semantics for external references than the
>ones defined on page 31 of K&R.

Dennis Ritchie did define the C language, but it was (and is) not a fixed
perfect creation.  There were several compilers for the C language which
implemented features differently.  K&R has a number of areas which are 
open to interpretation.

External variable linkage is one of those areas where the description in
K&R differed from what the compiler and linker on Unix actually did.  
Most pre-ANSI compilers and linkers would permit multiple definitions of
a variable outside a function, providing that there was only one initializer.
Some others didn't.  At least with the ANSI standard, there is a clear
definition of what is supposed to happen.  And you can still write the 
same code, using the same conventions you were using before.  The standard
mostly affect the obscure cases which were subject to different interpretation
by different compilers.

On another point, C has always had (and needed) forward references.  This
is both in functions and in structure definitions.  I fail to see how this
is an insinuation of anything into the language.

-- Mike Eager