A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.
Hey, all -
I'm trying to get back into C++ since my first exposure to it in school. I had an algorithms class that was taught in C++, but as expected, the programming there was largely language independent and provided only syntactic knowledge of C++. I'm trying to build this up a bit into something I could potentially use professionally down the road.
I'm curious whether anyone actually uses the "extern", "register" and other memory keywords that the language specifies. Are these holdovers from C, when compilers weren't smart enough to beat humans at memory allocation? Do modern dev tools even pay attention to them anymore? The book I am working with describes the "how", but not the "why" so to speak.
For most of those keywords, I do use them much differently between C and C++. Although, some might get used less in C++.
The use of some of these keywords is related to program design: e.g., "extern", "static" and heap vs. stack. OTOH, I rarely even think about using "register".
I have not quite figured out what you mean by "when compilers weren't smart enough to beat humans at memory allocation?" C and C++ are languages where the programmer is concerned about memory allocation and deallocation. Some people think that is a bad thing and use Java or some other language with GC.
Wednesday, June 04, 2008
You won't see "register" much anymore. It's a holdover from when C++ programmers knew better than the compiler how registers should be allocated. Similar to "inline", it's usually just a suggestion to the compiler, which is free to ignore it.
Extern you probably won't see much anymore either, but for a different reason. It's just as valid as it used to be, but the styles of programming that required it (e.g. global variables) have fallen out of fashion (replaced by e.g. OOP).
Wednesday, June 04, 2008
Just to pile on:
register -- not in common use currently because it was
just a way to signal the compiler that the variable
in question was likely to be used often and should,
if possible, be allocated in a register rather than
in main memory. Modern compilers are much better at
figuring out when a variable should be in a register
than are mere humans.
static -- still used in C for two purposes: 1. hide an
item from inter-file linkage, and 2. make a local
variable keep it's value between function calls.
These uses signal INTENT rather than USAGE and can't
be inferred by the compiler.
In C++ the first use has been overtaken by class
visibility modifiers (public, private and protected),
but the second use is still valid for declaring
"class level" members.
extern -- still used in C to indicate that a name is
actually declared in a different linkage unit and
will be resolved at link time. Most of this is
handled in C++ by class visibility modifiers but
you might still need this in rare instances (not
all C++ code is OO code). This is also a signal of
INTENT rather than USAGE and can't be inferred by
auto -- the default storage class for local variables.
I have never seen this used in the wild.
typedef -- technically this is a storage class specifier
indicating that the name being defined has no
corresponding storage associated with it. In C++
the role of typedef is mostly overtaken by classes,
but typedef is still in common use. This is also a
signal of INTENT rather than USAGE and can't be
inferred by the compiler.
inline -- this is a function specifier and indicates that
the function call should be made as fast as possible,
usually by replacing the call with the actual code of
the function body. This is in common use in C++ and
has recently (ISO C99 standard) been added to C. It
comes with a fair number of restrictions that you
should be aware of. See the fifth edition of "C: A
Reference Manual" by Harbison and Steele, or the
third edition of "Effective C++" by Scott Meyers for
all the gory details.
There are also three type qualifiers: const, volatile and restrict. The volatile and restrict qualifiers are fairly abstruse. While you are probably familiar with the const qualifier, it also has some more unusual uses. In all three cases you should refer to both general references (e.g. "C: A Reference Manual") for all the gory details.
Wednesday, June 04, 2008
extern has nothing to do with memory or storage allocation. It is used to signal that an identifier is being declared here but will be defined in another compilation unit. When applied to function prototypes it is meaningless to the compiler but I still use it to signal that the function is defined elsewhere, not just later on in the current compilation unit. When applied to a variable declaration, however, it is required. To see why, consider declaring a variable in a header file without declaring it as extern and each file that #includes the header file will get its own copy of the variable. By declaring it as extern (an defining it in a single compilation unit) you avoid this problem.
The register storage modifier is likely to be ignored by most modern compilers. I do embedded firmware development and have used that keyword precisely once in 9 years.
volatile is something you need to understand. If you have two threads that read/write to a common variable, that variable should be declared as volatile. In the embedded world it is common to have code like this (simplified for the purpose of illustration):
for(Flag = false; !Flag; );
The global variable Flag will be set to true within an interrupt (or another thread), causing the loop to terminate, so declaring Flag as volatile forces the compiler to generate code to check the memory location occupied by the Flag variable each iteration of the loop, not just copy its value into a register and constantly check the register's value (which will never be updated).
The difference between the uses of static is another good thing to be aware of. In C, static indicates that a variable is allocated off the stack; likely, but not necessarily, as part of the executable. (It will also be initialized to zero, unlike automatic variables.) When applied to a variable or function it also precludes the symbol from being exported to the linker (so you cannot share the variable across compilation units). Within the context of a class, static has a different meaning. Anything declared as static is shared across all instances of a class. An implication of this is that static functions do not have a "this" pointer passed to them implicitly.
I have seen the auto keyword used only once, but it is redundant and likely to cause confusion with inexperienced developers so I advise avoiding it.
Wednesday, June 04, 2008
> Don't forget: volatile -- this value will change without program interaction, and must be re-read from memory every time it is used.
Forgetting "volatile" can cause a problem which only happens when the compiler's optimizations are enabled (and doesn't happen in "debug mode" when you compile with optimizations disabled).
Externs are also used when you need to "export" C++ variables or functions to be used from other applications written in another language eg. VC++ and called from VB. You place the "extern" keyword before the function or variable name and also list them down in your .def file. They also prevent function names from being mangled which some C compilers seem to do automatically.
Thursday, June 05, 2008
This topic is archived. No further replies will be accepted.Other recent topics
Powered by FogBugz