Thinking in C++ Notes(8)
Chapter 8: Constants
Value substitution
- preprocessor simply does text replacement and has no concept nor facility for type checking.
- You should always use const instead of #define value substitution.
- Normally, the C++ compiler avoids creating storage for a const, but instead holds the definition in its symbol table.
- When you use extern with const, you force storage to be allocated and constant folding is prevented.
- When using const for aggregates, the const value cannot be used at compile time.
const int i[]={1,2,3,4};
float f[i[2]];//Illegal - Differences with C:
- const in C:
- "an ordinary variable that cannot be changed."
- always occupies storage and its name is global
- cannot be treated as a compile-time constant
- C defaults to external linkage for consts, C++ defaults to internal linkage for consts.
Pointer:
- Pointer to const
const int* u;
int const* u;u is a pointer, which point to a const int.
u can be a lvalue while *u cannot. - const pointer
int d=1;
int* const w=&d;w is a pointer, which is const, that points to an int.
*w can be a lvalue while w cannot.
const value must be initialized at the definition.
Assignment and type checking
- you can assign a non-const object to a const pointer, but you cannot assign a const object to a non-const pointer.
but you can "casting away constness":
const int e=2;
int* w=(int*)&e; //Legal but bad practice - a problem:
char* cp="hello";
/* this is technically an error because you assign a const array address to an non-const pointer, but the compiler will accept it without complaint, you modify the array through cp is a runtime error */
char p[]="world";// if you want modify the string, define it like this
Function arguments and return values
- when passing objects by values, specifying const has no meaning.
to avoid confusion to the caller, you can make the argument a const inside the function by const reference. - returning consts by value has no meaning for built-in types.
return a const value means it cannot be an lvalue(cannot be assigned or modified) - In C++, your first choice when passing an argument is to pass by const reference
Const in classes
- const inside a class means "This is constant for the lifetime of the object."
However, each different object may contain a different value for that constant. - constructor initializer list: const data member must be initialized in the list
- static const of a built-in type can be treated as a compile-time constant.
static const member must be initialized at the point of definition. - "enum hack"
define an untagged enum in your class then you can use enum value as compile-time constant.
class Bunch {
enum { size = 1000 };
int i[size];
}; - mutable:
bitwise const: every bit in the object is pemanent.
logical const: although the entire object is conceptually constant, there may be changes on a member-by-member basis.
2 way to change a data member from within a const member function:
- casting away constness(cast "this" pointer)
- use mutable keyword to specify the data member may be changed inside a const object.
Volatile
volatile means "this data may change outside the knowledge of the compiler."(multi-task,multi-thread,interrupts)
Last modified on 2007-06-12