[RoarAudio] When to use the 'const' keyword and when to use #define
Philipp Schafft
lion at lion.leolix.org
Tue Aug 30 22:12:35 CEST 2011
flum,
I often see the const keyword missused. So here is some clarification
from my side when to use it. Maybe someone may find it useful.
Firt of all, what does const do, what does #define do?
const:
It tells the compiler that it is allowed to mark the data read
only the in the current scope. The allocation, storage, usage
and aliasing rules are unchanged by this.
If used in the declaration of some object the compliler is
allowed to ask the rest of the toolchain (mainly the linker) to
put this object into a read only segment. This can be ignored by
the compiler, linker and the OS.
#define:
This is used for simple string substitution. The constant
defined using #define is just put litterally where the symbolic
name appears.
This is all done by the preprocessor. The compiler, linker and
other parts of the toolchain do not know about this.
No space is allocated for the defined constants.
Some implications the above stuff has:
An object declarated with const needs space in the programm
binary and in the RAM of the process. It needs a symbol in the
symbol table, needs to be resolved by the linker and by the
dynamic linker. It may need runtime code to initialize.
As the const keyword may be ignored at diffrent levels the
content is can not be assumed to be truly read only and is
subject to overwrite problems such as buffer overflows.
If they are auto variables ('local vars of a function') they are
on the stack and CAN NOT be protected for overwrite. A simple
overflow or pointer miscalculation will lead into overwriting.
As they are variables the compiler can only do very few more
optimization with them. It can not run any compile time code
substituation (for example a 'const div = 2; b = a / div;'
requires a full divider run, not a simple bitshift).
On the other pow there is the #define:
No symbol is created. no space is allocated (expect on use, see
below).
The value is true constant. It's hard to overwrite a literal.
How the compiler stores the constant is up to the compiler.
The compiler does this context sensetive.
For example if you set some variable to such an value the
compiler will normally generate an single machine instroduction
which contains the value it it's opcode (mov on ix86, ldi on
AVR, ...).
In the above example the compiler will detect that 'devide by
two' is the same as a single right shift and it will generate a
ror instroduction.
Such code is much faster and may save a lot space.
Also if a #define-ed constant is not used it does not need any
resources unlike using 'const' which always allocates space.
This is important if you have a list of harly used constants
'const' would require significant space.
The pro of #define that the value is embedded is also it's only
big negative point: It is embedded in the code it uses. It is
embedded very time it is used. For integer or float constants,
and small strings this is no problem. This is a problem on large
objects which are used often. For example lookup tables with
several thousends of entrys. Such arrays or other complex
objects are also hardly subject to big optimisatzion (for
example accessing a fixed index in a big array can be optimized,
accessing a random index can't.). For such objects 'const'
normally fits better.
So, what to use? The easy rule:
Is your constant something small (fits into a single register,
or the part used?) -> #define
Is your object big (normally > 16, 32, ... bytes)? -> const
Another myth about const:
As stuff declared const is a normal object and because of this
accessable by all normal object operations it must be in a data
segment of the resulting binary. This also means that on a
Harvard architecture those objects can NOT be stored in the
programm memory. The loader part of the program needs to
allocate RAM and initializes it with the data from the program
memory. This requires lots of resources: RAM and program memory
(the data is duplicated) and loader code. There is no standard
way to put data in the program memory of such systems as well as
no standard way to operate with it. You need to look up your
compiler's documentation about this if needed.
Thanks for reading! Hope it helped some of you :)
--
Philipp.
(Rah of PH2)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 482 bytes
Desc: This is a digitally signed message part
URL: <http://lists.keep-cool.org/pipermail/roaraudio/attachments/20110830/31ab21ef/attachment-0001.pgp>
More information about the RoarAudio
mailing list