RE: [Sdcc-user] libraries and global variables

Dear Lawrence,
in ANSI-C and C++ "static" in front of a variable outside a function
simply meens NOT global. A function declared as static is only visible
inside of the compilation module (.c -file) in which it is defined. This
was different in K-R C, but this is obsolete now. This is a bit
non-obvious, but the language lawyers probably couldn't think of a
better keyword for this.
Best regards,
Michael
> -----Original Message-----
> From: sdcc-user-admin@...
> [mailto:sdcc-user-admin@...]On Behalf Of Lawrence
> Johnson
> Sent: Thursday, May 30, 2002 10:18 PM
> To: sdcc-user@...
> Subject: [Sdcc-user] libraries and global variables
>
>
> This is possibly more of a programming question than an SDCC
> question,
> but I'm not sure, so I'll start here:
>
> With sdcc created libraries that use global variables, such
> as circular
> buffers for serial ports, presumably the variables must be declared
> global in the library source, or the source of one of the library
> functions. These same variables must be declared as extern
> ... in every
> other place they're used, such as an application that may need access.
>
> I mentioned serial ports above because that's what I'm
> currently fiddling
> around with on an AT89C2051. The serial port functions are based on
> those of Wolfgang Esslinger, as mentioned in the sdcc manual.
> My first
> question, is that in looking into the contents of _ser.c,
> there is a bit
> variable:
>
> static bit ser_txBusy;
>
> This is declared outside of any function, hence it is global,
> I think.
> If this is the case, my question is: Why?
>
> I looked through some old programming documentation on
> storage classes
> and it isn't ever stated that you can't do this, but this may
> be because
> nobody would ever want to, unless there's a reason I don't see.
>
> When I was trying to link in functions from a library based
> on _ser.c, I
> kept getting this stubborn warning about ser_txBusy being declared as
> global and not being defined anywhere, even if I put the
> declaration as a
> global in my application (meaning right above main). After a
> while, I
> started to question why this needs to be static, so I changed the
> declaration to simply read:
>
> bit ser_txBusy;
>
> ...and it now compiles, well sort of. The next problem that cropped
> might be related to sdcc.
>
> The block of variables is as follows:
>
> unsigned char ser_txIndexIn;
> unsigned char ser_txIndexOut;
> unsigned char ser_rxIndexIn;
> unsigned char ser_rxIndexOut;
>
> unsigned char ser_txBuffer[TXBUF];
> unsigned char ser_rxBuffer[RXBUF];
>
> static bit ser_txBusy;
>
> What I did, initially, was create discrete functions one per
> file, with
> the file names identical to the functions.
>
> (John McClintock: I was already well into this before you
> responded to
> my post of yesterday, so it was too late to turn back.)
>
> In each file, I declared the above block as:
>
> extern unsigned char ser_txIndexIn;
> extern unsigned char ser_txIndexOut;
> extern unsigned char ser_rxIndexIn;
> extern unsigned char ser_rxIndexOut;
>
> extern unsigned char ser_txBuffer[TXBUF];
> extern unsigned char ser_rxBuffer[RXBUF];
>
> extern static bit ser_txBusy;
>
> ...in all files except for ser_init.c, which obviously is the
> initialisation routine. In that file, I declared without
> extern. When I
> tried to then compile a program with only the initialisation
> routine and
> interrupt handler, I would get a "Multiple definition of
> _ser_rxBuffer"
> followed by a crash. It strikes me as a little strange that
> it wouldn't
> complain about any of the other variables. I checked and
> rechecked this
> because I couldn't see where the error was coming from.
> Eventually, I
> changed the above block of variables to all be extern in all
> functions
> and placed a global declaration in the header file for the would-be
> library. The global declaration was wrapped within:
>
> #ifndef _SERLIB
> #define _SERLIB
> <global variables go here>
> #endif
>
> and the compile step had a -D_SERLIB on it for building the
> library. I,
> of course, don't put the -D_SERLIB on the command-line for
> building the
> application, so the block gets declared there.
>
> Why didn't the global declaration in ser_init.c work? Should it have
> worked at all? This would have been much simpler in my
> books, and since
> you can't do anything without the initialisation step, you
> must end up
> declaring the global variables there, but not so.
>
>
>
> ______________________________________________________
> Lawrence Johnson J-Tech Engineering Ltd
> 1050 Quadling Avenue Coquitlam BC Canada V3K 2B2
> Tel 604 936 7468 Fax 604 936 7426 Cel 604 802 7579
> http://www.jtecheng.com
>
>
> _______________________________________________________________
>
> Don't miss the 2002 Sprint PCS Application Developer's Conference
> August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm
>
> _______________________________________________
> Sdcc-user mailing list
> Sdcc-user@...
> https://lists.sourceforge.net/lists/listinfo/sdcc-user

Thread view

This is possibly more of a programming question than an SDCC question,
but I'm not sure, so I'll start here:
With sdcc created libraries that use global variables, such as circular
buffers for serial ports, presumably the variables must be declared
global in the library source, or the source of one of the library
functions. These same variables must be declared as extern ... in every
other place they're used, such as an application that may need access.
I mentioned serial ports above because that's what I'm currently fiddling
around with on an AT89C2051. The serial port functions are based on
those of Wolfgang Esslinger, as mentioned in the sdcc manual. My first
question, is that in looking into the contents of _ser.c, there is a bit
variable:
static bit ser_txBusy;
This is declared outside of any function, hence it is global, I think.
If this is the case, my question is: Why?
I looked through some old programming documentation on storage classes
and it isn't ever stated that you can't do this, but this may be because
nobody would ever want to, unless there's a reason I don't see.
When I was trying to link in functions from a library based on _ser.c, I
kept getting this stubborn warning about ser_txBusy being declared as
global and not being defined anywhere, even if I put the declaration as a
global in my application (meaning right above main). After a while, I
started to question why this needs to be static, so I changed the
declaration to simply read:
bit ser_txBusy;
...and it now compiles, well sort of. The next problem that cropped
might be related to sdcc.
The block of variables is as follows:
unsigned char ser_txIndexIn;
unsigned char ser_txIndexOut;
unsigned char ser_rxIndexIn;
unsigned char ser_rxIndexOut;
unsigned char ser_txBuffer[TXBUF];
unsigned char ser_rxBuffer[RXBUF];
static bit ser_txBusy;
What I did, initially, was create discrete functions one per file, with
the file names identical to the functions.
(John McClintock: I was already well into this before you responded to
my post of yesterday, so it was too late to turn back.)
In each file, I declared the above block as:
extern unsigned char ser_txIndexIn;
extern unsigned char ser_txIndexOut;
extern unsigned char ser_rxIndexIn;
extern unsigned char ser_rxIndexOut;
extern unsigned char ser_txBuffer[TXBUF];
extern unsigned char ser_rxBuffer[RXBUF];
extern static bit ser_txBusy;
...in all files except for ser_init.c, which obviously is the
initialisation routine. In that file, I declared without extern. When I
tried to then compile a program with only the initialisation routine and
interrupt handler, I would get a "Multiple definition of _ser_rxBuffer"
followed by a crash. It strikes me as a little strange that it wouldn't
complain about any of the other variables. I checked and rechecked this
because I couldn't see where the error was coming from. Eventually, I
changed the above block of variables to all be extern in all functions
and placed a global declaration in the header file for the would-be
library. The global declaration was wrapped within:
#ifndef _SERLIB
#define _SERLIB
<global variables go here>
#endif
and the compile step had a -D_SERLIB on it for building the library. I,
of course, don't put the -D_SERLIB on the command-line for building the
application, so the block gets declared there.
Why didn't the global declaration in ser_init.c work? Should it have
worked at all? This would have been much simpler in my books, and since
you can't do anything without the initialisation step, you must end up
declaring the global variables there, but not so.
______________________________________________________
Lawrence Johnson J-Tech Engineering Ltd
1050 Quadling Avenue Coquitlam BC Canada V3K 2B2
Tel 604 936 7468 Fax 604 936 7426 Cel 604 802 7579
http://www.jtecheng.com

Dear Lawrence,
in ANSI-C and C++ "static" in front of a variable outside a function
simply meens NOT global. A function declared as static is only visible
inside of the compilation module (.c -file) in which it is defined. This
was different in K-R C, but this is obsolete now. This is a bit
non-obvious, but the language lawyers probably couldn't think of a
better keyword for this.
Best regards,
Michael
> -----Original Message-----
> From: sdcc-user-admin@...
> [mailto:sdcc-user-admin@...]On Behalf Of Lawrence
> Johnson
> Sent: Thursday, May 30, 2002 10:18 PM
> To: sdcc-user@...
> Subject: [Sdcc-user] libraries and global variables
>
>
> This is possibly more of a programming question than an SDCC
> question,
> but I'm not sure, so I'll start here:
>
> With sdcc created libraries that use global variables, such
> as circular
> buffers for serial ports, presumably the variables must be declared
> global in the library source, or the source of one of the library
> functions. These same variables must be declared as extern
> ... in every
> other place they're used, such as an application that may need access.
>
> I mentioned serial ports above because that's what I'm
> currently fiddling
> around with on an AT89C2051. The serial port functions are based on
> those of Wolfgang Esslinger, as mentioned in the sdcc manual.
> My first
> question, is that in looking into the contents of _ser.c,
> there is a bit
> variable:
>
> static bit ser_txBusy;
>
> This is declared outside of any function, hence it is global,
> I think.
> If this is the case, my question is: Why?
>
> I looked through some old programming documentation on
> storage classes
> and it isn't ever stated that you can't do this, but this may
> be because
> nobody would ever want to, unless there's a reason I don't see.
>
> When I was trying to link in functions from a library based
> on _ser.c, I
> kept getting this stubborn warning about ser_txBusy being declared as
> global and not being defined anywhere, even if I put the
> declaration as a
> global in my application (meaning right above main). After a
> while, I
> started to question why this needs to be static, so I changed the
> declaration to simply read:
>
> bit ser_txBusy;
>
> ...and it now compiles, well sort of. The next problem that cropped
> might be related to sdcc.
>
> The block of variables is as follows:
>
> unsigned char ser_txIndexIn;
> unsigned char ser_txIndexOut;
> unsigned char ser_rxIndexIn;
> unsigned char ser_rxIndexOut;
>
> unsigned char ser_txBuffer[TXBUF];
> unsigned char ser_rxBuffer[RXBUF];
>
> static bit ser_txBusy;
>
> What I did, initially, was create discrete functions one per
> file, with
> the file names identical to the functions.
>
> (John McClintock: I was already well into this before you
> responded to
> my post of yesterday, so it was too late to turn back.)
>
> In each file, I declared the above block as:
>
> extern unsigned char ser_txIndexIn;
> extern unsigned char ser_txIndexOut;
> extern unsigned char ser_rxIndexIn;
> extern unsigned char ser_rxIndexOut;
>
> extern unsigned char ser_txBuffer[TXBUF];
> extern unsigned char ser_rxBuffer[RXBUF];
>
> extern static bit ser_txBusy;
>
> ...in all files except for ser_init.c, which obviously is the
> initialisation routine. In that file, I declared without
> extern. When I
> tried to then compile a program with only the initialisation
> routine and
> interrupt handler, I would get a "Multiple definition of
> _ser_rxBuffer"
> followed by a crash. It strikes me as a little strange that
> it wouldn't
> complain about any of the other variables. I checked and
> rechecked this
> because I couldn't see where the error was coming from.
> Eventually, I
> changed the above block of variables to all be extern in all
> functions
> and placed a global declaration in the header file for the would-be
> library. The global declaration was wrapped within:
>
> #ifndef _SERLIB
> #define _SERLIB
> <global variables go here>
> #endif
>
> and the compile step had a -D_SERLIB on it for building the
> library. I,
> of course, don't put the -D_SERLIB on the command-line for
> building the
> application, so the block gets declared there.
>
> Why didn't the global declaration in ser_init.c work? Should it have
> worked at all? This would have been much simpler in my
> books, and since
> you can't do anything without the initialisation step, you
> must end up
> declaring the global variables there, but not so.
>
>
>
> ______________________________________________________
> Lawrence Johnson J-Tech Engineering Ltd
> 1050 Quadling Avenue Coquitlam BC Canada V3K 2B2
> Tel 604 936 7468 Fax 604 936 7426 Cel 604 802 7579
> http://www.jtecheng.com
>
>
> _______________________________________________________________
>
> Don't miss the 2002 Sprint PCS Application Developer's Conference
> August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm
>
> _______________________________________________
> Sdcc-user mailing list
> Sdcc-user@...
> https://lists.sourceforge.net/lists/listinfo/sdcc-user

Community

Help

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

I agree to receive quotes, newsletters and other information from sourceforge.net and its partners regarding IT services and products. I understand that I can withdraw my consent at any time. Please refer to our Privacy Policy or Contact Us for more details