2. sequence points
5.1.2.3 Program execution. Clause 2
At certain specified points in the
execution sequence called
sequence points, all side effects of
previous evaluations shall be
complete and no side effects of
subsequent evaluation shall have
taken place.
11. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
12. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
13. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
14. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
15. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
16. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
17. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
18. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
19. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
20. sequence points
Most C and C++ programmers use an implicit
mental model made up of lots of sequence points,
progressing in a mostly left-to-right order.
i + v[++i] + v[++i]
21. sequence points
In reality C and C++ have
very few sequence points
(this is to give maximum
scope for optimization).
22. sequence points where?
• at the end of a full expression
• after the first operand of these operators
&& || ?: ,
• after evaluation of all arguments and
the function call expression in a
function call
30. shall
If a "shall" or a "shall not" requirement
that appears outside of a constraint is
violated, the behavior is undefined.
4. Conformance. Clause 2
undefined behavior:
behavior ... for which this International
Standard imposes no requirements.
3.Terms, definitions, and symbols
31. sequence point: rule-one
Between the previous and next
sequence point an object shall have its
stored value modified at most once by
the evaluation of an expression.
n = n++;
6.5 Expressions. Clause 2.
undefined behavior
32. sequence point: rule-one
Between the previous and next
sequence point an object shall have its
stored value modified at most once by
the evaluation of an expression.
n = n++;
6.5 Expressions. Clause 2.
undefined behavior
33. sequence point: rule-two
Between the previous and next
sequence point the prior value shall be
read only to determine the value to be
stored.
n + n++;
6.5 Expressions. Clause 2.
undefined behavior
34. sequence point: rule-two
Between the previous and next
sequence point the prior value shall be
read only to determine the value to be
stored.
n + n++;
6.5 Expressions. Clause 2.
undefined behavior
35. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
(Mac OS 10.8.2)
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
36. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
(Mac OS 10.8.2)
$ gcc foo.c && ./a.out
12
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
37. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
$ clang foo.c && ./a.out
clang
(Mac OS 10.8.2)
$ gcc foo.c && ./a.out
12
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
38. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
$ clang foo.c && ./a.out
clang
(Mac OS 10.8.2)
$ gcc foo.c && ./a.out
12
$ clang foo.c && ./a.out
11
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
39. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
$ clang foo.c && ./a.out
clang
$ icc foo.c && ./a.out
icc
(Mac OS 10.8.2)
$ gcc foo.c && ./a.out
12
$ clang foo.c && ./a.out
11
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
40. example
#include <stdio.h>
int main(void)
{
int v[] = { 0,2,4,6,8 };
int i = 1;
int n = i + v[++i] + v[++i];
printf("%dn", n);
}
$ gcc foo.c && ./a.out
gcc
$ clang foo.c && ./a.out
clang
$ icc foo.c && ./a.out
icc
(Mac OS 10.8.2)
$ gcc foo.c && ./a.out
12
$ clang foo.c && ./a.out
11
$ icc foo.c && ./a.out
13
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
64. indeterminate value
6.2.4 Storage duration of objects
The initial value of the object is
indeterminate.
J.2 Undefined behavior
The value of an object with
automatic storage duration is
used while it is indeterminate.
65. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc
Without optimization...
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
66. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc
Without optimization...
true
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
67. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang
Without optimization...
true
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
68. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang
Without optimization...
true false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
69. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
true false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
70. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
true false true
false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
71. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
72. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
73. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
74. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
false false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
75. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
false false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
76. example
#include <stdio.h>
#include <stdbool.h>
void bar(void)
{
bool b;
if (b)
printf("truen");
if (!b)
printf("falsen");
}
void foo(void);
void bar(void);
int main(void)
{
foo();
bar();
}
void foo(void)
{
char c = 2;
...
}
gcc clang icc
Without optimization...
With optimization...
true false true
false
false false false
http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf
121. Debugging is twice as hard as
writing the code in the first
place. Therefore, if you write
the code as cleverly as possible,
you are, by definition, not smart
enough to debug it.
125. virtual destructor
class random_dice_roller
: public
dice_roller
{
public:
...
};
answer:
any code can delete a derived object
through a base class pointers*
void contrived_example()
{
dice_roller * ptr =
new random_dice_roller();
...
delete ptr;
}
* and it will work!
126. virtual destructor
class random_dice_roller
: public
dice_roller
{
public:
...
};
answer:
any code can delete a derived object
through a base class pointers*
void contrived_example()
{
dice_roller * ptr =
new random_dice_roller();
...
delete ptr;
}
* and it will work!
127. virtual destructor?
class random_dice_roller
: public
dice_roller
{
public:
...
};
question:
should any code be able to write
delete expressions?
void contrived_example()
{
dice_roller * ptr =
new random_dice_roller();
...
delete ptr;
}
class dice_roller
{
public:
virtual ~dice_roller();
...
};
128. virtual destructor
suppose you don't want arbitrary code to
be able to write delete expressions?
void contrived_example()
{
dice_roller * ptr =
new random_dice_roller();
...
delete ptr;
}
class dice_roller
{
public:
...
protected:
~dice_roller();
};
150. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
class snafu;
class widget;
class fubar
{
...
};
#endif
namespace fishing
{
class snafu
{
...
};
}
fubar.hpp
fishing/snafu.hpp
namespace fishing
{
class widget
{
...
};
}
fishing/widget.hpp
151. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
namespace fishing
{
class snafu;
class widget;
}
class fubar
{
...
};
#endif
fubar.hpp
namespace fishing
{
class snafu
{
...
};
}
fishing/snafu.hpp
namespace fishing
{
class widget
{
...
};
}
fishing/widget.hpp
152. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
namespace std
{
class string;
}
class fubar
{
...
};
#endif
namespace std
{
class string
{
...
};
}
fubar.hpp <string>
it's not like this!
153. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
namespace std
{
class string;
}
class fubar
{
...
};
#endif
namespace std
{
template<typename T>
class basic_string
{
...
};
typedef basic_string<char> string;
...
}
fubar.hpp <string>
it's a bit like this!
154. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
namespace std
{
template<typename T>
class basic_string;
typdef
basic_string<char>
string;
}
class fubar
{
...
};
#endif
namespace std
{
template<typename T>
class basic_string
{
...
};
typedef basic_string<char> string;
...
}
fubar.hpp <string>
?
?
155. you must not tell lies!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
namespace std
{
template<typename T>
class basic_string;
typdef
basic_string<char>
string;
}
class fubar
{
...
};
#endif
namespace std
{
template<typename T1,
typename T2 = ...,
typename T3 = ...>
class basic_string
{
...
};
typedef basic_string<char> string;
...
}
fubar.hpp <string>
default template types
169. include your own header 1st
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
#include <vector>
class fubar
{
public:
...
void fu();
...
private:
std::vector<wibble> wibbles;
};
#endif
#include "fubar.hpp"
...
void fubar::fu()
{
...
}
fubar.hpp fubar.cpp
170. better still - make sure each
header compiles (on its own) as
part of the build!
#ifndef FUBAR_INCLUDED
#define FUBAR_INCLUDED
#include "wibble.hpp"
#include <vector>
class fubar
{
public:
...
void fu();
...
private:
std::vector<wibble> wibbles;
};
#endif
fubar.hpp