Skip to main content
added 389 characters in body
Source Link
gnasher729
  • 47.5k
  • 4
  • 68
  • 133

I'd start with C and C++, where things are reasonably simple. You have "objects" in memory, not in the sense of object oriented programming, but items that can be read or changed. These "objects" can be "const", which means an attempt to modify them invokes undefined behaviour. Often the compiler will not allow you to modify a const object, but there are ways around that. Typically behaviours when you try to modify a const object are:

Your application crashes
Your application doesn't store the value
Your application gets into a schizophrenic state whether the object is modified or not
The object is modified

And most common: You don't notice anything wrong in development, but as soon as you deliver your software to a customer, it will fail in the worst possible way.

Apart from objects being constant, pointers to objects may allow modification or not. There are rules for this that are usually sensible, but this being C or C++ you can override them.

int i = 10;
const int* p = &i;
int* q = (int*) p; 

The object i is not constant, but you are not allowed to modify it through the pointer p. You are allowed to modify it through q though. Now take the example

const int i = 10;
const int* p = &i;
int* q = (int*) p; 

i is not modifiable. The compiler won't let you change i through the pointer p. The compiler will let you attempt to change i through the pointer q, but will produce undefined behaviour.

If you have a class or struct that is const, then normally all members are const. There are two exceptions: When you run a C++ constructor, the object members can be modified until the constructor has finished (const instances of class would be quite useless otherwise). There is another exception: If a member is "mutable" then it can be modified and is not const even when it is part of a const object. This is useful for caches, for example. Consider a string class with 0-terminated strings and a function that returns the length. To determine the length, you need to go through all the elements until you find the trailing 0 which is expensive, so you would like to store the length. You can do that by storing the length in a mutable member. So calling the len(function) changes the object, but doesn't logically change it.

In C and C++, classes and structs are not const; it is the individual instances that are const or not. const pointer members mean that the pointer value cannot be changed, but if the pointer points to modifiable data then the data it points to can be changed. This means that you may be able for example to change the title of a const button, which may come very unexpected. So you need to distinguish between "logically unmodifiable" and "physically unmodifiable".

Another unexpected thing: You can have a modifiable object, and both a const and a non-const pointer to it. If I pass a const int * p to a function, the developer may assume that *p cannot change. But if I have an int *q pointing to the same variable then it can change. And a compiler can usually create better code if it knows that an object cannot change - which it often can’t.

I'd start with C and C++, where things are reasonably simple. You have "objects" in memory, not in the sense of object oriented programming, but items that can be read or changed. These "objects" can be "const", which means an attempt to modify them invokes undefined behaviour. Often the compiler will not allow you to modify a const object, but there are ways around that. Typically behaviours when you try to modify a const object are:

Your application crashes
Your application doesn't store the value
Your application gets into a schizophrenic state whether the object is modified or not
The object is modified

And most common: You don't notice anything wrong in development, but as soon as you deliver your software to a customer, it will fail in the worst possible way.

Apart from objects being constant, pointers to objects may allow modification or not. There are rules for this that are usually sensible, but this being C or C++ you can override them.

int i = 10;
const int* p = &i;
int* q = (int*) p; 

The object i is not constant, but you are not allowed to modify it through the pointer p. You are allowed to modify it through q though. Now take the example

const int i = 10;
const int* p = &i;
int* q = (int*) p; 

i is not modifiable. The compiler won't let you change i through the pointer p. The compiler will let you attempt to change i through the pointer q, but will produce undefined behaviour.

If you have a class or struct that is const, then normally all members are const. There are two exceptions: When you run a C++ constructor, the object members can be modified until the constructor has finished (const instances of class would be quite useless otherwise). There is another exception: If a member is "mutable" then it can be modified and is not const even when it is part of a const object. This is useful for caches, for example. Consider a string class with 0-terminated strings and a function that returns the length. To determine the length, you need to go through all the elements until you find the trailing 0 which is expensive, so you would like to store the length. You can do that by storing the length in a mutable member. So calling the len(function) changes the object, but doesn't logically change it.

In C and C++, classes and structs are not const; it is the individual instances that are const or not. const pointer members mean that the pointer value cannot be changed, but if the pointer points to modifiable data then the data it points to can be changed. This means that you may be able for example to change the title of a const button, which may come very unexpected. So you need to distinguish between "logically unmodifiable" and "physically unmodifiable".

I'd start with C and C++, where things are reasonably simple. You have "objects" in memory, not in the sense of object oriented programming, but items that can be read or changed. These "objects" can be "const", which means an attempt to modify them invokes undefined behaviour. Often the compiler will not allow you to modify a const object, but there are ways around that. Typically behaviours when you try to modify a const object are:

Your application crashes
Your application doesn't store the value
Your application gets into a schizophrenic state whether the object is modified or not
The object is modified

And most common: You don't notice anything wrong in development, but as soon as you deliver your software to a customer, it will fail in the worst possible way.

Apart from objects being constant, pointers to objects may allow modification or not. There are rules for this that are usually sensible, but this being C or C++ you can override them.

int i = 10;
const int* p = &i;
int* q = (int*) p; 

The object i is not constant, but you are not allowed to modify it through the pointer p. You are allowed to modify it through q though. Now take the example

const int i = 10;
const int* p = &i;
int* q = (int*) p; 

i is not modifiable. The compiler won't let you change i through the pointer p. The compiler will let you attempt to change i through the pointer q, but will produce undefined behaviour.

If you have a class or struct that is const, then normally all members are const. There are two exceptions: When you run a C++ constructor, the object members can be modified until the constructor has finished (const instances of class would be quite useless otherwise). There is another exception: If a member is "mutable" then it can be modified and is not const even when it is part of a const object. This is useful for caches, for example. Consider a string class with 0-terminated strings and a function that returns the length. To determine the length, you need to go through all the elements until you find the trailing 0 which is expensive, so you would like to store the length. You can do that by storing the length in a mutable member. So calling the len(function) changes the object, but doesn't logically change it.

In C and C++, classes and structs are not const; it is the individual instances that are const or not. const pointer members mean that the pointer value cannot be changed, but if the pointer points to modifiable data then the data it points to can be changed. This means that you may be able for example to change the title of a const button, which may come very unexpected. So you need to distinguish between "logically unmodifiable" and "physically unmodifiable".

Another unexpected thing: You can have a modifiable object, and both a const and a non-const pointer to it. If I pass a const int * p to a function, the developer may assume that *p cannot change. But if I have an int *q pointing to the same variable then it can change. And a compiler can usually create better code if it knows that an object cannot change - which it often can’t.

Source Link
gnasher729
  • 47.5k
  • 4
  • 68
  • 133

I'd start with C and C++, where things are reasonably simple. You have "objects" in memory, not in the sense of object oriented programming, but items that can be read or changed. These "objects" can be "const", which means an attempt to modify them invokes undefined behaviour. Often the compiler will not allow you to modify a const object, but there are ways around that. Typically behaviours when you try to modify a const object are:

Your application crashes
Your application doesn't store the value
Your application gets into a schizophrenic state whether the object is modified or not
The object is modified

And most common: You don't notice anything wrong in development, but as soon as you deliver your software to a customer, it will fail in the worst possible way.

Apart from objects being constant, pointers to objects may allow modification or not. There are rules for this that are usually sensible, but this being C or C++ you can override them.

int i = 10;
const int* p = &i;
int* q = (int*) p; 

The object i is not constant, but you are not allowed to modify it through the pointer p. You are allowed to modify it through q though. Now take the example

const int i = 10;
const int* p = &i;
int* q = (int*) p; 

i is not modifiable. The compiler won't let you change i through the pointer p. The compiler will let you attempt to change i through the pointer q, but will produce undefined behaviour.

If you have a class or struct that is const, then normally all members are const. There are two exceptions: When you run a C++ constructor, the object members can be modified until the constructor has finished (const instances of class would be quite useless otherwise). There is another exception: If a member is "mutable" then it can be modified and is not const even when it is part of a const object. This is useful for caches, for example. Consider a string class with 0-terminated strings and a function that returns the length. To determine the length, you need to go through all the elements until you find the trailing 0 which is expensive, so you would like to store the length. You can do that by storing the length in a mutable member. So calling the len(function) changes the object, but doesn't logically change it.

In C and C++, classes and structs are not const; it is the individual instances that are const or not. const pointer members mean that the pointer value cannot be changed, but if the pointer points to modifiable data then the data it points to can be changed. This means that you may be able for example to change the title of a const button, which may come very unexpected. So you need to distinguish between "logically unmodifiable" and "physically unmodifiable".