441
Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful containing only well defined and conforming code. Why do professional programmers write code like this? Because most programmers do not have a deep understanding of the language they are using. While they sometimes know that certain things are undefined or unspecified, they often do not know why it is so. In this presentation we will study small code snippets in C and C++, and use them to discuss the fundamental building blocks, limitations and underlying design philosophies of these wonderful but dangerous programming languages. Deep C (and C++) http://www.noaanews.noaa.gov/stories2005/images/rov-hercules-titanic.jpg by Olve Maudal A 3 hour course for students at NTNU Monday, October 14, 2012

by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful containing only well defined and conforming code. Why do professional programmers write code like this? Because most programmers do not have a deep understanding of the language they are using. While they sometimes know that certain things are undefined or unspecified, they often do not know why it is so. In this presentation we will study small code snippets in C and C++, and use them to discuss the fundamental building blocks, limitations and underlying design philosophies of these wonderful but dangerous programming languages.

Deep C (and C++)

http://www.noaanews.noaa.gov/stories2005/images/rov-hercules-titanic.jpg

by Olve Maudal

A 3 hour course for students at NTNU Monday, October 14, 2012

Page 2: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 3: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 4: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 5: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 6: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c$ ./foo

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 7: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c$ ./foo11

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 8: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c$ ./foo11$ cc -Wall -Wextra -pedantic -o foo foo.c

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 9: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c$ ./foo11$ cc -Wall -Wextra -pedantic -o foo foo.c$ ./foo

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 10: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise

$ cc -o foo foo.c$ ./foo11$ cc -Wall -Wextra -pedantic -o foo foo.c$ ./foo11

#include <stdio.h>

int main(void){ int v[] = {2,4,6,8,10,12}; int i = 1; int n = ++i + v[++i]; printf("%d\n", n);}

foo.c

Type in this code. Compile and execute the program. What do you get?

Page 12: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 13: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Aristotles Universe

Aristotle (384 BC – 322 BC)

Page 14: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Aristotles Universe

Aristotle (384 BC – 322 BC)

Ptolemy Universe

Ptolemy (90 AD – 168 AD)

Page 15: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Aristotles Universe

Aristotle (384 BC – 322 BC)

Ptolemy Universe

Ptolemy (90 AD – 168 AD) Copernicus (1473 – 1543)

The Solar System

Page 16: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Strange explanations are often symptoms of having an invalid conceptual model!

Page 17: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 18: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp

Page 19: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out

Page 20: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out4

Page 21: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out44

Page 22: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

Page 23: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

Page 24: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 25: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp

Page 26: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out

Page 27: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out4

Page 28: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out45

Page 29: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out456

Page 30: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out456

Page 31: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 32: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

garbage, garbage, garbage?

Page 33: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0

Page 34: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

Page 35: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 36: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 37: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 38: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out1

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 39: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out12

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 40: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ static int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out123

garbage, garbage, garbage? No. In C++, variables

with static storage duration are initialized to their default value,

in this case 0It is better to

initialize explicitly.

I agree, in this case. But you still need to

know that it is so. And it is very useful to know why it is so

Page 41: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 42: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

1, 1, 1?

Page 43: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Page 44: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 45: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 46: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 47: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 48: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out1

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 49: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out12

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 50: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out123

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1? No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 51: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out123

Yes, in theory that is correct. Let’s try it on

my machine

1, 1, 1?

Ehh...

No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 52: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out123

Yes, in theory that is correct. Let’s try it on

my machine

any plausible explaination for this

behaviour?

1, 1, 1?

Ehh...

No, variables with automatic storage

duration is not initialized implicitly

Garbage, garbage, garbage

Page 53: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

I don’t need to know,

because I let the compiler find bugs like

this

Page 54: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 55: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 56: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp $ ./a.out

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 57: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp $ ./a.out1

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 58: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp $ ./a.out12

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 59: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp $ ./a.out123

OK, let’s add some flags

I don’t need to know,

because I let the compiler find bugs like

this

Page 60: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -Wall -Wextra foo.cpp $ ./a.out123

OK, let’s add some flags

Lousy compiler!

I don’t need to know,

because I let the compiler find bugs like

this

Page 61: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 62: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Pro tip: Compile with optimization!

Page 63: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -O -Wall -Wextra foo.cpp

Pro tip: Compile with optimization!

Page 64: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -O -Wall -Wextra foo.cpp foo.cpp: In function 'void foo()':

Pro tip: Compile with optimization!

Page 65: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ -O -Wall -Wextra foo.cpp foo.cpp: In function 'void foo()':foo.cpp:6: warning: 'a' is used uninitialized in this function

Pro tip: Compile with optimization!

Page 66: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 67: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

I am now going to show you something cool!

Page 68: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

I am now going to show you something cool!

Page 69: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

$ c++ foo.cpp && ./a.out

I am now going to show you something cool!

Page 70: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Page 71: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Can you explain this behaviour?

Page 72: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Can you explain this behaviour?

Page 73: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

eh?

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Can you explain this behaviour?

Page 74: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

eh?

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Perhaps this compiler has a pool of named variables that it reuses. Eg

variable a was used and released in bar(), then when foo() needs an integer names a it will get the

variable will get the same memory location. If you rename the variable in bar() to, say b, then I don’t think

you will get 42.

Can you explain this behaviour?

Page 75: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a; std::cout << a << std::endl;}

void bar(){ int a = 42;} int main(){ bar(); foo();}

eh?

$ c++ foo.cpp && ./a.out42

I am now going to show you something cool!

Perhaps this compiler has a pool of named variables that it reuses. Eg

variable a was used and released in bar(), then when foo() needs an integer names a it will get the

variable will get the same memory location. If you rename the variable in bar() to, say b, then I don’t think

you will get 42.

Yeah, sure...

Can you explain this behaviour?

Page 76: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 77: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why do you think static variables gets a default value (usually 0), while auto variables does not get a default value?

Page 78: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why do you think static variables gets a default value (usually 0), while auto variables does not get a default value?

Because C++ is a braindead programming

language?

Page 79: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why do you think static variables gets a default value (usually 0), while auto variables does not get a default value?

Because C++ is a braindead programming

language?

Because C++ (and C) is all about execution speed. Setting static

variables to default values is a one time cost, while defaulting auto

variables is a signficant runtime cost.

Page 80: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

Page 81: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out

Page 82: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347

Page 83: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

Page 84: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

but you might also get

Page 85: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

but you might also get

Page 86: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

but you might also get

or

Page 87: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

but you might also get

437437

or

Page 88: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

but you might also get

437437

or or

Page 89: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

but you might also get

437437

347347

or or

Page 90: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int foo(int a) { std::cout << a; return a;}

int bar(int a, int b) { return a + b;}

int main() { int i = foo(3) + foo(4); std::cout << i << std::endl;

int j = bar(foo(3), foo(4)); std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out347437

437347

C and C++ are among the few programming languages where evaluation

order is mostly unspecified. This is an example of unspecified behaviour.but you might also get

437437

347347

or or

Page 91: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why is the evaluation order mostly unspecified?

Page 92: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why is the evaluation order mostly unspecified?

Page 93: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why is the evaluation order mostly unspecified?

Because C++ is a braindead programming

language?

Page 94: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

In C++. Why is the evaluation order mostly unspecified?

Because C++ is a braindead programming

language?

Because there is a design goal to allow optimal execution speed on a wide range of architectures. In C++ the compiler can choose to evaluate expressions in the order that is most optimal for a particular platform. This

allows for great optimization.

Page 95: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

Page 96: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out

Page 97: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

Page 98: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

What? Inconceivable!

Page 99: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

What? Inconceivable!

This is a classic example of undefined behaviour. Anything can happen! Nasal demons can start flying out of your nose!

Page 100: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

What? Inconceivable!

This is a classic example of undefined behaviour. Anything can happen! Nasal demons can start flying out of your nose!I agree this is crap

code, but why is it wrong?

Page 101: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

What? Inconceivable!

This is a classic example of undefined behaviour. Anything can happen! Nasal demons can start flying out of your nose!I agree this is crap

code, but why is it wrong?

In this case? Line 6. What is i*3? Is it 2*3 or 3*3 or something else? In C++ you can not assume anything about a variable with side-

effects (here i++) before there is a sequence point.

Page 102: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

I don’t care, I never write code like that.

Page 103: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

Good for you. But bugs like this can easily happen if you don’t understand the rules of sequencing. And very often, the compiler is

not able to help you...

I don’t care, I never write code like that.

Page 104: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

Good for you. But bugs like this can easily happen if you don’t understand the rules of sequencing. And very often, the compiler is

not able to help you...

I don’t care, I never write code like that.

But why do we not get warning

on this by default?

Page 105: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int v[6] = {4,6,2,9}; int i = 2; int j = i * 3 + v[i++]; std::cout << j << std::endl;}

$ c++ foo.cpp && ./a.out42

Good for you. But bugs like this can easily happen if you don’t understand the rules of sequencing. And very often, the compiler is

not able to help you...

I don’t care, I never write code like that.

But why do we not get warning

on this by default?At least two reasons. First of all it is sometimes

very difficult to detect such sequencing violations. Secondly, there is so much existing code out there that breaks these rules, so issuing warnings here

might cause other problems.

Page 106: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

A sequence point is a point in the program's execution sequence where all previous side-effects shall have taken place and where all subsequent side-effects shall not have taken place

Sequence Points

Page 107: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.

Sequence Points - Rule 1

a = a++

this is undefined!

Page 108: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Furthermore, the prior value shall be read only to determine the value to be stored.

Sequence Points - Rule 2

a + a++

this is undefined!!

Page 109: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Sequence Points

A lot of developers think C++ has many sequence points

Page 110: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Sequence Points

The reality is that C++ has very few sequence points.

This helps to maximize optimization opportunitiesfor the compiler.

Page 111: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

Page 112: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++; printf("%d\n", a);1

Page 113: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ & printf("%d\n", a);2

int a=41; a++; printf("%d\n", a);1

Page 114: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; a++ & printf("%d\n", a);2

int a=41; a++; printf("%d\n", a);1

Page 115: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2

int a=41; a++; printf("%d\n", a);1

Page 116: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1

Page 117: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1

int a=41; a = foo(a++); printf("%d\n", a);6

Page 118: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

int a=41; a = foo(a++); printf("%d\n", a);6

Page 119: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

int a=41; a = foo(a++); printf("%d\n", a);6

Page 120: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

42

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

int a=41; a = foo(a++); printf("%d\n", a);6

Page 121: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

42

42

int a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

int a=41; a = foo(a++); printf("%d\n", a);6

Page 122: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

42

42

undefinedint a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

int a=41; a = foo(a++); printf("%d\n", a);6

Page 123: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

42

42

undefinedint a=41; a = a++; printf("%d\n", a);5

int a=41; a++; printf("%d\n", a);1 42

?int a=41; a = foo(a++); printf("%d\n", a);6

Page 124: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

What do these code snippets print?

int a=41; a++ && printf("%d\n", a);3

int a=41; if (a++ < 42) printf("%d\n", a);4

int a=41; a++ & printf("%d\n", a);2 undefined

42

42

undefinedint a=41; a = a++; printf("%d\n", a);5

When exactly do side-effects take place in C and C++?

int a=41; a++; printf("%d\n", a);1 42

?int a=41; a = foo(a++); printf("%d\n", a);6

Page 125: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 126: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; ++a; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 127: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

Page 128: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp

Page 129: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out

Page 130: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out4

Page 131: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out44

Page 132: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

Page 133: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

Believe it or not, I have met several

programmers who thought this snippet would print 3,3,3.

Page 134: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

They are all morons!

Believe it or not, I have met several

programmers who thought this snippet would print 3,3,3.

Page 135: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

They are all morons!

Believe it or not, I have met several

programmers who thought this snippet would print 3,3,3.

Did you know about sequence points? Do

you have a deep understanding of when side-effects really take

place in C++?

Page 136: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

void foo(){ int a = 3; a++; std::cout << a << std::endl;} int main(){ foo(); foo(); foo();}

$ c++ foo.cpp $ ./a.out444

They are all morons!

Believe it or not, I have met several

programmers who thought this snippet would print 3,3,3.

Did you know about sequence points? Do

you have a deep understanding of when side-effects really take

place in C++?

ehh...

Page 137: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Behavior

implementation-defined behavior: the construct is not incorrect; the code must compile; the compiler must document the behavior

unspecified behavior: the same as implementation-defined except the behavior need not be documented

undefined behavior: the standard imposes no requirements ; anything at all can happen, all bets are off, nasal demons might fly out of your nose.

#include <stdio.h>#include <limits.h>#include <stdlib.h>

int main(){ // implementation-defined int i = ~0; i >>= 1; printf("%d\n", i);

// unspecified output printf("4") + printf("2"); printf("\n");

// undefined int k = INT_MAX; k += 1; printf("%d\n", k);}

Note that many compilers will not give you any warnings when compiling this code, and due to the undefined behavior caused by signed integer overflow above, the whole program is in theory undefined.

Page 138: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Behavior

implementation-defined behavior: the construct is not incorrect; the code must compile; the compiler must document the behavior

unspecified behavior: the same as implementation-defined except the behavior need not be documented

undefined behavior: the standard imposes no requirements ; anything at all can happen, all bets are off, nasal demons might fly out of your nose.

#include <stdio.h>#include <limits.h>#include <stdlib.h>

int main(){ // implementation-defined int i = ~0; i >>= 1; printf("%d\n", i);

// unspecified output printf("4") + printf("2"); printf("\n");

// undefined int k = INT_MAX; k += 1; printf("%d\n", k);}

Note that many compilers will not give you any warnings when compiling this code, and due to the undefined behavior caused by signed integer overflow above, the whole program is in theory undefined.

... and, locale-specific behavior

Page 139: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

the C++ standard defines the expected behaviour, but says very little about how it should be implemented.

Page 140: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

the C++ standard defines the expected behaviour, but says very little about how it should be implemented.

this is a key feature of C++, and one of the reason why C++ is such a successful programming language on a wide range of hardware!

Page 141: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

Page 142: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

$ c++ foo.cpp && ./a.out

Page 143: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

$ c++ foo.cpp && ./a.outThe answer is 44

Page 144: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

$ c++ foo.cpp && ./a.outThe answer is 44

Inconceivable!

Page 145: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

$ c++ foo.cpp && ./a.outThe answer is 44

Inconceivable!You keep using that word. I do not think it

means what you think it means.

Page 146: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>#include <climits>

int main() { int i = INT_MAX; int j = i + 1 - 1; if (j == INT_MAX) std::cout << "The answer is 42" << std::endl; else std::cout << "The answer is 43" << std::endl;}

$ c++ foo.cpp && ./a.outThe answer is 44

Remember... when you have undefined behavior, anything can happen!

Inconceivable!You keep using that word. I do not think it

means what you think it means.

Page 147: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

bool b;if (b) printf("b is true\n");if (!b) printf("b is false\n");

A real story of “anything can happen”

Page 148: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

bool b;if (b) printf("b is true\n");if (!b) printf("b is false\n");

; the following code assumes that $b is either 0 or 1

load_a $b ; load value of b into register A compare_a 0 ; compare register A to 0 jump_equal label1 ; skip next statement if A == 0 call print_b_is_true ; print “b is true”label1: load_a $b ; load value of b into register A xor_a 1 ; xor register A with 1 compare_a 0 ; compare register A to 0 jump_equal label2 ; skip next statement if A == 0 call print_b_is_false ; print “b is false”label2:

A real story of “anything can happen”

Page 149: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

bool b;if (b) printf("b is true\n");if (!b) printf("b is false\n");

; the following code assumes that $b is either 0 or 1

load_a $b ; load value of b into register A compare_a 0 ; compare register A to 0 jump_equal label1 ; skip next statement if A == 0 call print_b_is_true ; print “b is true”label1: load_a $b ; load value of b into register A xor_a 1 ; xor register A with 1 compare_a 0 ; compare register A to 0 jump_equal label2 ; skip next statement if A == 0 call print_b_is_false ; print “b is false”label2:

A real story of “anything can happen”

this is approximately the code generated by gcc for an intel platform, try to imagine what will happen if b is 42

Page 150: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

bool b;if (b) printf("b is true\n");if (!b) printf("b is false\n");

; the following code assumes that $b is either 0 or 1

load_a $b ; load value of b into register A compare_a 0 ; compare register A to 0 jump_equal label1 ; skip next statement if A == 0 call print_b_is_true ; print “b is true”label1: load_a $b ; load value of b into register A xor_a 1 ; xor register A with 1 compare_a 0 ; compare register A to 0 jump_equal label2 ; skip next statement if A == 0 call print_b_is_false ; print “b is false”label2:

b is trueb is false

A real story of “anything can happen”

this is approximately the code generated by gcc for an intel platform, try to imagine what will happen if b is 42

Page 151: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 152: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Page 153: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte. Yes, on my machine it is

Page 154: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

So you get 9?

Yes, on my machine it is

Page 155: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Could be, but this is what I get on my

machine

So you get 9?

Yes, on my machine it is

Page 156: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Could be, but this is what I get on my

machine$ c++ foo.cpp && ./a.out

So you get 9?

Yes, on my machine it is

Page 157: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Could be, but this is what I get on my

machine$ c++ foo.cpp && ./a.out12

So you get 9?

Yes, on my machine it is

Page 158: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Could be, but this is what I get on my

machine$ c++ foo.cpp && ./a.out12

Yeah of course, I forgot about that, because in C++ the structs are padded

to so size becomes multiple 4

So you get 9?

Yes, on my machine it is

Page 159: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

I guess integers are 4 bytes and char is 1 byte.

Could be, but this is what I get on my

machine$ c++ foo.cpp && ./a.out12

Yeah of course, I forgot about that, because in C++ the structs are padded

to so size becomes multiple 4 Kind of...

So you get 9?

Yes, on my machine it is

Page 160: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

So what if I add a member function?

Page 161: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;};

int main(){ std::cout << sizeof(X) << std::endl;}

So what if I add a member function?

Page 162: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 163: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 164: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 165: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Now this code will print 16. Because there will be a pointer to the function.

Page 166: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Now this code will print 16. Because there will be a pointer to the function.

ok?

Page 167: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Now this code will print 16. Because there will be a pointer to the function.

ok?

Lets add two more functions...

Page 168: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 169: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; }

};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 170: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 171: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Then it will print 24. Two more pointers.

Page 172: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Then it will print 24. Two more pointers.

This is what I get on my machine

Page 173: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Then it will print 24. Two more pointers.

$ c++ foo.cpp && ./a.out

This is what I get on my machine

Page 174: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Then it will print 24. Two more pointers.

$ c++ foo.cpp && ./a.out12

This is what I get on my machine

Page 175: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Then it will print 24. Two more pointers.

$ c++ foo.cpp && ./a.out12

This is what I get on my machineHuh? Probably some weird optimization going on, perhaps because the functions are never called.

Page 176: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 177: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 178: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Because adding member functions like this does not change the size of the struct. In C++, the object does not know about it’s functions, it is the functions

that know about the object.

Page 179: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Because adding member functions like this does not change the size of the struct. In C++, the object does not know about it’s functions, it is the functions

that know about the object.

If you rewrite this into C it becomes obvious.

Page 180: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

C++

struct X { int a; char b; int c;};

void set_value(struct X * this, int v) { this->a = v; }int get_value(struct X * this) { return this->a; }void increase_value(struct X * this) { this->a++; }

C

Page 181: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 182: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 183: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out

Page 184: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out24

Page 185: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out24

Ehh...

Page 186: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } int get_value() { return a; } void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out24

Ehh...

Page 187: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } virtual int get_value() { return a; } virtual void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

Page 188: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } virtual int get_value() { return a; } virtual void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

48?

Page 189: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } virtual int get_value() { return a; } virtual void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out48?

Page 190: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } virtual int get_value() { return a; } virtual void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out24

48?

Page 191: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 192: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

struct X { int a; char b; int c;

virtual void set_value(int v) { a = v; } virtual int get_value() { return a; } virtual void increase_value() { a++; }};

int main(){ std::cout << sizeof(X) << std::endl;}

$ c++ foo.cpp && ./a.out24

Page 193: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

The vtable

struct base{ virtual void f(); virtual void g(); int a,b;};

struct derived : base{ virtual void g(); virtual void h(); int c;};

void poly(base * ptr){ ptr->f(); ptr->g();}

int main(){ poly(&base()); poly(&derived());}

base::f() {}

base::g() {}

f

gvptr

ab

0

1

base objectbase

vtable

vptr

a

b

c

fgh

0

1

derived objectderived vtable

derived::g() {}

derived::h() {}2

Page 194: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

The vtable

struct base{ virtual void f(); virtual void g(); int a,b;};

struct derived : base{ virtual void g(); virtual void h(); int c;};

void poly(base * ptr){ ptr->f(); ptr->g();}

int main(){ poly(&base()); poly(&derived());}

base::f() {}

base::g() {}

f

gvptr

ab

0

1

base objectbase

vtable

vptr

a

b

c

fgh

0

1

derived objectderived vtable

derived::g() {}

derived::h() {}2

This is a common way of implementing virtual functions in C++

Page 195: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Let’s move up one abstraction level

Page 196: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 197: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

Page 198: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

Page 199: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

Page 200: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

This is a piece of shitty C++ code. Is this your code? First of all....

Page 201: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

This is a piece of shitty C++ code. Is this your code? First of all....

never use 2 spaces for indentation.

Page 202: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

This is a piece of shitty C++ code. Is this your code? First of all....

never use 2 spaces for indentation.

The curly brace after class A should definitely start on a new line

Page 203: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Take a look at this piece of code. Pretend like I am a junior C++ programmer joining your team. Here is a piece of code that I might present to you. Please

be pedantic and try to gently introduce me to pitfalls of C++ and perhaps teach me something about the C++ way of doing things.

This is a piece of shitty C++ code. Is this your code? First of all....

never use 2 spaces for indentation.

The curly brace after class A should definitely start on a new line

sz_? I have never seen that naming convention, you should always use the GoF standard _sz or the Microsoft standard m_sz.

Page 204: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 205: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Do you see anything else?

Page 206: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Do you see anything else?

eh?

Page 207: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Do you see anything else?

eh? Oh yes, I guess you know that in C++ all destructors should always be declared as virtual. I read it in some book and it is very important to

avoid slicing when deleting objects of subtypes.

Page 208: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Do you see anything else?

eh? Oh yes, I guess you know that in C++ all destructors should always be declared as virtual. I read it in some book and it is very important to

avoid slicing when deleting objects of subtypes.

or something like that...

Page 209: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful
Page 210: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 211: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 212: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 213: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 214: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

Page 215: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete v; } // ...private: // ... B * v; int sz_;};

When you allocate an array, you must delete an array. Otherwise the

destructors will not be called correctly.

Page 216: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

Page 217: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

Page 218: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

In this case, since you have a destructor like this, you must either implement or hide the copy constructor and

assignment operator. This is called the rule of three, if you implement one of them, you must deal with them all.

Page 219: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

Page 220: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

Page 221: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: // ... B * v; int sz_;};

Page 222: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 223: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 224: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;}; Not using the initializer list is usually a strong sign that the

programmer does not really understand how to use C++. It does not make sense to first give member variables their

default value, and then assign them a value.

Page 225: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) { sz_ = sz; v = new B[sz_]; } ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 226: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz) { v = new B[sz_]; } ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 227: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz), v(new B[sz_]) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 228: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz), v(new B[sz_]) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

oups! we just introduced a terrible bug!

Page 229: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz), v(new B[sz_]) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

oups! we just introduced a terrible bug!

Page 230: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz), v(new B[sz]) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 231: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : sz_(sz), v(new B[sz]) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 232: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : v(new B[sz]), sz_(sz) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

Page 233: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : v(new B[sz]), sz_(sz) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

?

Page 234: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include "B.hpp"

class A {public: A(int sz) : v(new B[sz]), sz_(sz) {} ~A() { delete[] v; } // ...private: A(const A &); A & operator=(const A &); // ... B * v; int sz_;};

?

Bald pointers are also often a sign of not using C++ correctly. When you see them, there are usually better ways of writing the code. In this case, perhaps a std::vector<B> is

what you want?

Page 235: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Summary

Page 236: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model

Summary

Page 237: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order

Summary

Page 238: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points

Summary

Page 239: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior

Summary

Page 240: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior• optimization

Summary

Page 241: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior• optimization• vtables

Summary

Page 242: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior• optimization• vtables• object lifetimes

Summary

Page 243: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior• optimization• vtables• object lifetimes• rule of 3

Summary

Page 244: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

• memory model• evaluation order• sequence points• undefined vs unspecified behavior• optimization• vtables• object lifetimes• rule of 3• initialization of objects

Summary

Page 245: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Aristotles Universe

Aristotle (384 BC – 322 BC)

Ptolemy Universe

Ptolemy (90 AD – 168 AD) Copernicus (1473 – 1543)

The Solar System

Page 246: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

C and C++ are not really high level languages, they are more like portable assemblers. When programming in C and C++ you must have a understanding of what happens under the hood! And if you don’t have a decent understanding of it, then you are doomed to create lots of bugs...

Page 247: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

C and C++ are not really high level languages, they are more like portable assemblers. When programming in C and C++ you must have a understanding of what happens under the hood! And if you don’t have a decent understanding of it, then you are doomed to create lots of bugs...

But if you do have a useful mental model of what happens under the hood, then...

Page 249: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

!

Page 250: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

Quick!

Page 251: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp

Quick!

Page 252: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp $ ./a.out

Quick!

Page 253: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp $ ./a.out3

Quick!

Page 254: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp $ ./a.out3$ c++ -Wall -Wextra -pedantic foo.cpp

Quick!

Page 255: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp $ ./a.out3$ c++ -Wall -Wextra -pedantic foo.cpp $ ./a.out

Quick!

Page 256: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <iostream>

int main() { int i = 4; i =+ 3; std::cout << i << std::endl;}

$ c++ foo.cpp $ ./a.out3$ c++ -Wall -Wextra -pedantic foo.cpp $ ./a.out3

Quick!

Page 257: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

The spirit of C

trust the programmer• let them do what needs to be done• the programmer is in charge not the compiler

keep the language small and simple• small amount of code → small amount of assembler• provide only one way to do an operation• new inventions are not entertained

make it fast, even if its not portable• target efficient code generation • int preference, int promotion rules• sequence points, maximum leeway to compiler

rich expression support• lots of operators• expressions combine into larger expressions

Page 258: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

•C++ is designed to be a statically typed, general-purpose language that is as efficient and portable as C

•C++ is designed to directly and comprehensively support multiple programming styles (procedural programming, data abstraction, object-oriented programming, and generic programming)

•C++ is designed to give the programmer choice, even if this makes it possible for the programmer to choose incorrectly

•C++ is designed to be as compatible with C as possible, therefore providing a smooth transition from C

•C++ avoids features that are platform specific or not general purpose

•C++ does not incur overhead for features that are not used (the "zero-overhead principle")

•C++ is designed to function without a sophisticated programming environment

Design principles for C++

Page 259: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Bonus material

Page 260: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

A Brief Tourtools and vocabulary

(a chapter from Deep C - a 3 day course by Jon Jagger & Olve Maudal)

Page 261: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

A Brief Tourtools and vocabulary

not so

(a chapter from Deep C - a 3 day course by Jon Jagger & Olve Maudal)

Page 262: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 263: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 264: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c$ ./hello

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 265: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c$ ./helloThe answer is 42

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 266: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c$ ./helloThe answer is 42$ echo $?

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 267: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c$ ./helloThe answer is 42$ echo $?0

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 268: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Hello World!

$ cc -o hello hello.c$ ./helloThe answer is 42$ echo $?0$

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

hello.c

Type in this code. Compile and execute the program. What do you get?

Page 269: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this the result you expected?

Page 270: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this the result you expected?

Of course it was!

Page 271: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

But let’s do a dry run and step through the code

Was this the result you expected?

Of course it was!

Page 272: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

But let’s do a dry run and step through the code

(we will look at the compilation step later. )

Was this the result you expected?

Of course it was!

Page 273: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

But let’s do a dry run and step through the code

The following is an example of what might happen when executing this code:

(we will look at the compilation step later. )

Was this the result you expected?

Of course it was!

Page 274: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 275: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

After some basic initialization the run-time environment will call the

main function.

Page 276: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 277: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

then preparation for the call to calc() starts by evaluating all the arguments to be passed to the function.

Page 278: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

? ? ?

guess which argument is evaluated first?

Page 279: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 280: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

unlike other popular programming laugages, the order of evaluation is mostly unspecified in C. In this case the

compiler or runtime environment might choose to evaluate life() first

Page 281: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 282: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 283: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 284: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, 6 , everything()); printf("The answer is %d\n", a);}

Page 285: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, 6 , everything()); printf("The answer is %d\n", a);}

Page 286: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, 6 , everything()); printf("The answer is %d\n", a);}

universe is replaced with 7.

Page 287: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , everything()); printf("The answer is %d\n", a);}

Page 288: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , everything()); printf("The answer is %d\n", a);}

Page 289: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , everything()); printf("The answer is %d\n", a);}

Page 290: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , everything()); printf("The answer is %d\n", a);}

Page 291: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , everything()); printf("The answer is %d\n", a);}

Page 292: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 293: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 294: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

now we are ready to call the calc() function. This can be done by pushing arguments on an execution stack, reserve space for the return value and perhaps some housekeeping values.

Page 295: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

now we are ready to call the calc() function. This can be done by pushing arguments on an execution stack, reserve space for the return value and perhaps some housekeeping values.

? ? ?

Page 296: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

now we are ready to call the calc() function. This can be done by pushing arguments on an execution stack, reserve space for the return value and perhaps some housekeeping values.

? ? ?

guess which argument is pushed first?

Page 297: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

Page 298: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

Page 299: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

return address

Page 300: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

return address

space for return value

Page 301: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

return address

space for return value

1 first argument - a

Page 302: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

return address

space for return value

1 first argument - a

6 second argument - b

Page 303: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

the way arguments are passed to a function is defined by the calling convention (ABI) used by the compiler and runtime environment. Here is just an example...

return address

space for return value

1 first argument - a

6 second argument - b7 third argument - c

Page 304: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

activ

atio

n re

cord

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

Page 305: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

and when the “activation record” is populated, the program can jump into the function.

activ

atio

n re

cord

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

Page 306: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

and when the “activation record” is populated, the program can jump into the function.

activ

atio

n re

cord

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

Page 307: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 308: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

and then evaluate the expression.

Page 309: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 7 * 6 / 1;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 310: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 7 * 6 / 1;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 311: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 / 1;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 312: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 313: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

Page 314: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

Page 315: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

Page 316: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

42

Page 317: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

42

Page 318: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

42

jump back

Page 319: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc( 7 , 6 , 1 ); printf("The answer is %d\n", a);}

return address

1

6

7

space for return valuefirst argument - a

second argument - b

third argument - c

42

Page 320: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", a);}

Page 321: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", a);}

Page 322: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

Page 323: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

and then 42 and the pointer to the character string is pushed on the

execution stack before the library function printf() is called

Page 324: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

The printf() function writes out to the standard output stream

Page 325: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

The answer is 42

The printf() function writes out to the standard output stream

Page 326: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

The answer is 42

The printf() function writes out to the standard output stream

Page 327: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return 42 ;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = 42; printf("The answer is %d\n", 42);}

The answer is 42$ echo $?0

and a default value to indicate success, in this case 0, is returned back to the run-time environment

Page 328: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this exactly what you expected?

Page 329: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this exactly what you expected?

Good!

Page 330: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this exactly what you expected?

Good!

This was just an example of what might happen.

Page 331: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Was this exactly what you expected?

Good!

This was just an example of what might happen.

Because...

Page 332: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 333: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 334: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

Page 335: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

maybe the compiler is clever and see that life() and everything() always returns 6 and 1

Page 336: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

maybe the compiler is clever and see that life() and everything() always returns 6 and 1

Page 337: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = calc(universe, life(), everything()); printf("The answer is %d\n", a);}

maybe the compiler is clever and see that life() and everything() always returns 6 and 1

and then by inlining calc() perhaps the compiler choose to optimize the code into...

Page 338: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", a);}

Page 339: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", a);}

and since nobody else uses the functions perhaps the compiler decides to not create code for life() and calc()

Page 340: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", a);}

and since nobody else uses the functions perhaps the compiler decides to not create code for life() and calc()

Page 341: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", a);}

and since nobody else uses the functions perhaps the compiler decides to not create code for life() and calc()

Page 342: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", a);}

and since nobody else uses the functions perhaps the compiler decides to not create code for life() and calc()

and since variable a is used only here, then it might skip creating object a and just evaluate the expression as part of the printf() expression.

Page 343: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", universe * 6 / 1);}

Page 344: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", universe * 6 / 1);}

Page 345: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", universe * 6 / 1);}

But it will still print...

Page 346: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", universe * 6 / 1);}

The answer is 42$ echo $?0

But it will still print...

Page 347: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

static int calc(int a, int b, int c){ return a * b / c;}

int universe = 7;static int life(void) { return 6; }int everything(void) { return 1; }

int main(void){ int a = universe * 6 / 1; printf("The answer is %d\n", universe * 6 / 1);}

The key take away from this session is that things like execution stack and calling conventions are not dictated by the standard. The evaluation order of expressions and arguments is mostly unspecified. And the optimizer might rearrange the execution of the code significantly. In C, nearly everything can happen, and will happen, internally as long as the external behavior is satisfied.

The answer is 42$ echo $?0

But it will still print...

Page 348: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

the C standard defines the expected behaviour, but says very little about how it should be implemented.

Page 349: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

the C standard defines the expected behaviour, but says very little about how it should be implemented.

this is a key feature of C, and one of the reason why C is such a successful programming language on such a wide range of hardware!

Page 350: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Behavior

implementation-defined behavior: the construct is not incorrect; the code must compile; the compiler must document the behavior

unspecified behavior: the same as implementation-defined except the behavior need not be documented

undefined behavior: the standard imposes no requirements ; anything at all can happen, all bets are off, nasal demons might fly out of your nose.

#include <stdio.h>#include <limits.h>#include <stdlib.h>

int main(void){ // implementation-defined int i = ~0; i >>= 1; printf("%d\n", i);

// unspecified output printf("4") + printf("2"); printf("\n");

// undefined int k = INT_MAX; k += 1; printf("%d\n", k);}

Note that many compilers will not give you any warnings when compiling this code, and due to the undefined behavior caused by signed integer overflow above, the whole program is in theory undefined.

Page 351: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int a(void) { printf("a"); return 3; }int b(void) { printf("b"); return 4; }

int main(void){ int c = a() + b(); printf("%d\n", c);}

just to illustrate the point. What do you think will happen when we run this program?

Page 352: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int a(void) { printf("a"); return 3; }int b(void) { printf("b"); return 4; }

int main(void){ int c = a() + b(); printf("%d\n", c);}

just to illustrate the point. What do you think will happen when we run this program?

According to the C standard, this program will print:

Page 353: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int a(void) { printf("a"); return 3; }int b(void) { printf("b"); return 4; }

int main(void){ int c = a() + b(); printf("%d\n", c);}

just to illustrate the point. What do you think will happen when we run this program?

ba7

According to the C standard, this program will print:

Page 354: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int a(void) { printf("a"); return 3; }int b(void) { printf("b"); return 4; }

int main(void){ int c = a() + b(); printf("%d\n", c);}

just to illustrate the point. What do you think will happen when we run this program?

ba7 ab7or

According to the C standard, this program will print:

Page 355: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int a(void) { printf("a"); return 3; }int b(void) { printf("b"); return 4; }

int main(void){ int c = a() + b(); printf("%d\n", c);}

just to illustrate the point. What do you think will happen when we run this program?

ba7 ab7or

According to the C standard, this program will print:

Unlike most modern programming languages, the evaluation order of most expressions are not specified in C

Page 356: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

And while we are on a roll... What do you think might happen when we run this program?

Page 357: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

And while we are on a roll... What do you think might happen when we run this program?

Page 358: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

And while we are on a roll... What do you think might happen when we run this program?

you might get:

Page 359: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

And while we are on a roll... What do you think might happen when we run this program?

420

you might get:

Page 360: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

And while we are on a roll... What do you think might happen when we run this program?

420

you might get:

If you break the rules of the language, the behaviour of the whole program is undefined. Anything can happen! And the compiler will often not be able to give you a warning.

Page 361: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

And while we are on a roll... What do you think might happen when we run this program?

420

you might get:

If you break the rules of the language, the behaviour of the whole program is undefined. Anything can happen! And the compiler will often not be able to give you a warning.

Try it!

Page 362: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

Page 363: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

The violation here is that we are violating the rules of sequencing, which, among other things says that a variable can not be updated twice between two

sequence points.

Page 364: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

#include <stdio.h>

int main(void){ int v[] = {9,7,5,3,1}; int i = 2; int n = v[i++] - v[i++]; printf("%d\n", n); printf("%d\n", i); return 0;}

The violation here is that we are violating the rules of sequencing, which, among other things says that a variable can not be updated twice between two

sequence points.

$ gcc -O -Wall -Wextra -pedantic foo.c $ ./a.out04$

Here is what I get on my machine:

Page 365: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

We just had a glimpse of what might happen when code is executed.

Scary stuff? Not really, but with only a shallow understanding of the language it is easy to make big mistakes.

The goal of this course is to give you a deep understanding of C, by starting from scratch an relearn the language in a systematic way.

First, lets start to establish a vocabulary. To do that, we need an even more contrived example program...

Page 366: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 367: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

$ cc foo.c$ ./a.outHello everyone$ echo $?0

Page 368: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

$ cc foo.c$ ./a.outHello everyone$ echo $?0

Why do we need this?

Page 369: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

$ cc foo.c$ ./a.outHello everyone$ echo $?0

Why do we need this? and what does

this mean?

Page 370: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

$ cc foo.c$ ./a.outHello everyone$ echo $?0

Why do we need this?

how is a for loop really working?

and what does this mean?

Page 371: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

$ cc foo.c$ ./a.outHello everyone$ echo $?0

Why do we need this?

how is a for loop really working?

and what does this mean?

how many arguments does

this function accept?

Page 372: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

http://en.wikipedia.org/wiki/File:Basic_constituent_structure_analysis_English_sentence.svg

To get a deep understanding of any language you need to be able to ‘break’ it down and analyse it, at least you need to recognize the words used when experts are discussing among themselves

Page 373: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 374: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

keyword

Page 375: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

keyword

keyword

Page 376: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

keyword

keyword

keyword

Page 377: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 378: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

function prototype

Page 379: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

function prototype

function definition

Page 380: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

function prototype

function definition

(declaration)

Page 381: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 382: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

identifier with internal linkage

Page 383: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

identifier with internal linkage

linkage specification

Page 384: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

identifier with external linkage

identifier with internal linkage

linkage specification

Page 385: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 386: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

declaration with initialization

Page 387: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

declaration with initialization

declaration without initialization

Page 388: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

declaration with initialization

declaration without initialization

expression

Page 389: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

declaration with initialization

assignmentexpression

declaration without initialization

expression

Page 390: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

expression statement

declaration with initialization

assignmentexpression

declaration without initialization

expression

Page 391: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

expression statement

declaration with initialization

statement

assignmentexpression

declaration without initialization

expression

Page 392: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 393: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

type specifier

Page 394: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

type specifier

type qualifier

Page 395: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

type specifier

storage class specifier

type qualifier

Page 396: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

Page 397: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

comment

Page 398: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

comment

pre-processor directive

Page 399: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

comment

pre-processor directive

macro name

Page 400: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

int printf(const char * restrict, ...);void exit(int);#define EXIT_FAILURE 1

static void say_hello(const char * who){ printf("Hello %s\n", who);}

// compute the answerint the_answer(){ register int a; int b = 6; /* mystic base value */ a = 0; for (int i=0; i<7; i++) a += b; return a;}

const int life_universe_everything = 42;

int main(void){ say_hello("everyone"); int a = the_answer(); if (a != life_universe_everything) exit(EXIT_FAILURE);}

type specifier

function prototype

expression statement

declaration with initialization

function definition

expression

comment

external linkage

internal linkage

keyword

storage class specifier

statement

pre-processor directive

macro name

assignmentexpression

type qualifier

linkage specification

declaration without initialization

Page 401: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

A glimpse into tools often used when developing C

Page 402: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 403: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 404: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c$ cc -c theanswer.c

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 405: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c$ cc -c theanswer.c$ cc -o theanswer theanswer.o dt.o

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 406: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c$ cc -c theanswer.c$ cc -o theanswer theanswer.o dt.o$ ./theanswer

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 407: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c$ cc -c theanswer.c$ cc -o theanswer theanswer.o dt.o$ ./theanswerThe answer is 42

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 408: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 1

$ cc -c dt.c$ cc -c theanswer.c$ cc -o theanswer theanswer.o dt.o$ ./theanswerThe answer is 42$

#include "dt.h"#include <stdio.h>

int main(void){ dt_base_value = 6; int answer = dt_get_answer(); printf("The answer is %d\n", answer);}

theanswer.c

#include "dt.h"

int dt_base_value;#define MULTIPLIER 7static int dt_answer;

static void run_computer(void){ dt_answer = dt_base_value * MULTIPLIER;}

int dt_get_answer(void){ run_computer(); return dt_answer;}

dt.cextern int dt_base_value;int dt_get_answer(void);

dt.h

Page 409: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

dt.h

dt.c

preprocessor

dt.i

translator

dt.s

dt.o

theanswer

theanswer.c

theanswer.i

theanswer.s

theanswer.o

stdio.hpreprocessor

assembler

standard library (libc)

C run time (crt.o)

linker

translator

assembler

_dt_base_value_dt_get_answer

_main_dt_base_value_dt_get_answer_printf

_start_main

_printf...

Page 410: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

Page 411: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i

Page 412: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i

Page 413: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i

Page 414: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s

Page 415: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s

Page 416: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

Page 417: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c

Page 418: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c$ ls theanswer.*

Page 419: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c$ ls theanswer.*$ nm theanswer.o

Page 420: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c$ ls theanswer.*$ nm theanswer.o

$ ld -lc -o theanswer dt.o theanswer.o /usr/lib/crt1.o

Page 421: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c$ ls theanswer.*$ nm theanswer.o

$ ld -lc -o theanswer dt.o theanswer.o /usr/lib/crt1.o$ ./theanswer

Page 422: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 2

$ cc -E dt.c >dt.i$ cat dt.i$ cc -S dt.i$ cat dt.s$ cc -c dt.s$ nm dt.o

$ cc -c -save-temps theanswer.c$ ls theanswer.*$ nm theanswer.o

$ ld -lc -o theanswer dt.o theanswer.o /usr/lib/crt1.o$ ./theanswerThe answer is 42

Page 423: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

Page 424: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c

Page 425: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer

Page 426: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run

Page 427: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer

Page 428: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8

Page 429: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont

Page 430: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont(gdb) disassemble run_computer

Page 431: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont(gdb) disassemble run_computer(gdb) set disassembly-flavor intel

Page 432: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont(gdb) disassemble run_computer(gdb) set disassembly-flavor intel(gdb) disassemble run_computer

Page 433: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont(gdb) disassemble run_computer(gdb) set disassembly-flavor intel(gdb) disassemble run_computer(gdb) help

Page 434: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Exercise: Deep thought, Part 3

$ cc -g -o theanswer dt.c theanswer.c$ gdb theanswer(gdb) run(gdb) break run_computer(gdb) set dt_base_value = 8(gdb) cont(gdb) disassemble run_computer(gdb) set disassembly-flavor intel(gdb) disassemble run_computer(gdb) help(gdb) quit

Page 435: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

A few words about memory, activation frames and storage durations

Page 436: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Under the hood

Memory Layout and Activation Record

(This is a simplified view of how a possible memory layout might look like. Some architectures and run-time environment uses a very different layout and the C standard does not dictate how it should look like. However, without actually knowing the memory layout on your target machine, the description here is good enough as a conceptual model)

Page 437: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Text Segment

Data Segment

Execution Stack

Heap

high address

low address

Memory Layout *(automatic storage)

(allocated storage)

(static storage)

(instructions / read only data)

And sometimes it is useful to assume that an activation record is created and pushed onto the execution stack every time a function is called. The activation record contains local auto variables, arguments to the functions, and housekeeping data such as pointer to the previous frame and the return address.

Activation Record

housekeeping data

arguments

local auto variables

(*) The C standard does not dictate any particular memory layout, so what is presented here is just a useful conceptual example model that is similar to what some architecture and run-time enviornments look like

It is sometimes useful to assume that a C program uses a memory model where the instructions are stored in a text segment, and static variables are stored in a data segment. Automatic variables are allocated when needed together with housekeeping variables on an execution stack that is growing towards low address. The remaining memory, the heap is used for allocated storage.

The stack and the heap is typically not cleaned up in any way at startup, or during execution, so before objects are explicitly initialized they typically get garbage values based on whatever is left in memory from discarded objects and previous executions. In other words, the programmer must do all the housekeeping on variables with automatic storage and allocated storage.

Page 438: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Automatic storage durationVariables declared inside a “block”, eg the function body, come into existence when entering the block and disappears when exiting the block.* These objects have automatic storage class and they get an indeterminate initial value. Reading an indeterminate value causes undefined behavior. Referring to an object outside it’s lifetime also causes undefined behavior.

void function(int value){ int a; // ... { // ... int b; // ... } // ... int c; // ...}

(*) unless declared with the static keyword, see other slide

lifetime of object a, c and value

lifetime of object b

Page 439: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Static storage durationA variable declared outside a function scope, or with the static keyword inside a function, comes into existence and is initialized at program startup and its lifetime does not end until the program exits.

int global_var;

int next_value(void){ static int local_var = 39; local_var += 1; return local_var;}

int main(void){ next_value(); next_value(); printf("The answer is %d\n", next_value()); exit(0);}

lifetime of static variables, from program startup to program exit

initialized to 0 at program startup

initialized to 39 at program startup

increase the value of local_var every time this line expression is evaluated.

The answer is 42

Page 440: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Allocated storage duration

#include <stdlib.h>#include <stdio.h>

static int * b;

int main(void){ printf("The answer is"); b = malloc(sizeof b); *b = 42; printf(" %d\n", *b); free(b); b = 0;}

lifetime of the object that b is pointing to

The answer is 42

Page 441: by Olve Maudal - pvv.orgoma/DeepC_Abakus_Oct2012.pdf · Programming is hard. Programming correct C, and certainly C++, is particularly hard. Indeed, it is uncommon to see a screenful

Summary• hello world!• behaviour• vocabulary of the language• compiler, translator, assembler, linker• standard library and C run-time• memory layout and execution stack