14. Integer promotion
char c = ’X’;
cout << c;
cout << +c;
David Barina C/C++ tricks April 13, 2018 14 / 59
15. Polyglot
$CC -std=c90 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C90
$CC -std=c99 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C99
$CC -std=c11 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C11 or newer
$CXX -std=c++98 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C++03 or older
$CXX -std=c++03 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C++03 or older
$CXX -std=c++11 -pedantic -Wall -Wextra prog.c && ./a.out
I am compiled with C++11 or newer
David Barina C/C++ tricks April 13, 2018 15 / 59
16. Polyglot
if( sizeof(’a’) == sizeof(char) )
{
// compiled with C++
}
else
{
// compiled with C
}
David Barina C/C++ tricks April 13, 2018 16 / 59
27. Member call on null pointer
class A {
int x;
public:
void foo() {
std:: cout << "foo" << std:: endl;
x = 0;
}
};
int main () {
A *a = 0;
a->foo ();
}
David Barina C/C++ tricks April 13, 2018 27 / 59
28. Member call on null pointer
class A {
int x;
public:
void foo() {
std:: cout << "foo" << std:: endl;
x = 0;
}
};
int main () {
A *a = 0;
a->foo ();
}
foo
Neopr´avnˇen´y pˇr´ıstup do pamˇeti (SIGSEGV)
David Barina C/C++ tricks April 13, 2018 27 / 59
29. Member call on null pointer
class A {
int x;
public:
void bar() {
std:: cout << "bar" << std:: endl;
}
};
int main () {
A *a = 0;
a->bar ();
}
David Barina C/C++ tricks April 13, 2018 28 / 59
30. Member call on null pointer
class A {
int x;
public:
void bar() {
std:: cout << "bar" << std:: endl;
}
};
int main () {
A *a = 0;
a->bar ();
}
bar
David Barina C/C++ tricks April 13, 2018 28 / 59
31. Integer overflow
int a = /* something */;
int b = /* something */;
a += b;
if( a < 0 ) {
/* ... */
}
David Barina C/C++ tricks April 13, 2018 29 / 59
32. Integer overflow
int a = /* something */;
int b = /* something */;
a += b; /* UB */
if( a < 0 ) { /* unreliable test */
/* ... */
}
David Barina C/C++ tricks April 13, 2018 30 / 59
33. Integer overflow
int a = /* something */;
int b = /* something */;
if( /* test */ ) {
/* ... */
}
a += b;
David Barina C/C++ tricks April 13, 2018 31 / 59
35. Integer overflow
int a = /* something */;
int b = /* something */;
addition ‘a + b‘
if( (b > 0) && (a > INT_MAX - b) )
/* would overflow */;
if( (b < 0) && (a < INT_MIN - b) )
/* would overflow */;
David Barina C/C++ tricks April 13, 2018 33 / 59
36. Integer overflow
int a = /* something */;
int b = /* something */;
subtraction ‘a - b‘
if( (b < 0) && (a > INT_MAX + b) )
/* would overflow */;
if( (b > 0) && (a < INT_MIN + b) )
/* would overflow */;
David Barina C/C++ tricks April 13, 2018 34 / 59
37. Integer overflow
int a = /* something */;
int b = /* something */;
multiplication ‘a * b‘
if( (b != 0) && (a > INT_MAX / b) )
/* would overflow */;
if( (b != 0) && (a < INT_MIN / b) )
/* would overflow */;
David Barina C/C++ tricks April 13, 2018 35 / 59
38. Integer overflow
int a = /* something */;
int b = /* something */;
multiplication ‘a * b‘
if( (b != 0) && (a > INT_MAX / b) )
/* would overflow */;
if( (b != 0) && (a < INT_MIN / b) )
/* would overflow */;
if( (a == -1) && (b == INT_MIN) )
/* would overflow */;
if( (b == -1) && (a == INT_MIN) )
/* would overflow */;
David Barina C/C++ tricks April 13, 2018 35 / 59
39. Integer overflow
int a = /* something */;
int b = /* something */;
division ‘a / b‘
if( (b == -1) && (a == INT_MIN) )
/* would overflow */;
David Barina C/C++ tricks April 13, 2018 36 / 59
43. Implicit type conversion
char a = 5;
int b = a; /* implicit type conversion */
David Barina C/C++ tricks April 13, 2018 40 / 59
44. Implicit type conversion
int a = 5;
char b = a; /* implicit type conversion */
David Barina C/C++ tricks April 13, 2018 41 / 59
45. Implicit type conversion
int a = 300;
char b = a; /* alter a value */
David Barina C/C++ tricks April 13, 2018 42 / 59
46. Implicit type conversion
int i = -1;
unsigned int u = i; /* change the sign */
David Barina C/C++ tricks April 13, 2018 43 / 59
47. Implicit type conversion
-Wconversion
warning: conversion to ‘int’ from ‘long int’
may alter its value
warning: conversion to ‘unsigned char’ from ‘int’
may alter its value
-Wsign-conversion
warning: negative integer implicitly converted
to unsigned type
warning: conversion to ‘unsigned int’ from ‘int’
may change the sign of the result
David Barina C/C++ tricks April 13, 2018 44 / 59
48. Explicit type conversion (cast notation)
int a = 5;
char b = (char)a; /* no warning */
std:: cout << +b << std:: endl; // 5
David Barina C/C++ tricks April 13, 2018 45 / 59
49. Explicit type conversion (conversion operator)
int a = 5;
char b = static_cast <char >(a);
std:: cout << +b << std:: endl; // 5
David Barina C/C++ tricks April 13, 2018 46 / 59
50. Explicit type conversion (cast notation)
int a = 5;
double *b = (double *)&a; /* no warning */
std:: cout << *b << std:: endl; // 2.47033e -323
David Barina C/C++ tricks April 13, 2018 47 / 59
51. Explicit type conversion (conversion operator)
int a = 5;
double *b = static_cast <double *>&a;
error: invalid static_cast from type ‘int*’
to type ‘double*’
David Barina C/C++ tricks April 13, 2018 48 / 59
52. Explicit type conversion (conversion operator)
int a = 5;
double *b = reinterpret_cast <double *>(&a);
std:: cout << *b << std:: endl; // 2.47033e -323
David Barina C/C++ tricks April 13, 2018 49 / 59
53. Explicit type conversion
( new_type ) expression
const_cast<new_type>(expression)
static_cast<new_type>(expression)
static_cast followed by const_cast
reinterpret_cast<new_type>(expression)
reinterpret_cast followed by const_cast
David Barina C/C++ tricks April 13, 2018 50 / 59
54. Explicit type conversion (cast notation)
-Wold-style-cast
warning: use of old-style cast
David Barina C/C++ tricks April 13, 2018 51 / 59
55. Initializer lists
class A {
int i;
public:
A() { i = 0; } // default
A(int i_) { i = i_; } // init
A& operator =(int i_) { i = i_; } // init
};
class B {
A a;
public:
B() { a = 3; } // default , init
};
David Barina C/C++ tricks April 13, 2018 52 / 59
56. Initializer lists
class A {
int i;
public:
A() { i = 0; } // default
A(int i_) { i = i_; } // init
A& operator =(int i_) { i = i_; } // init
};
class B {
A a;
public:
B() : a(3) {} // init
};
David Barina C/C++ tricks April 13, 2018 53 / 59
57. const member
class A {
public:
const int i;
A(int i_) { i = i_; }
};
error: assignment of read-only member ‘A::i’
David Barina C/C++ tricks April 13, 2018 54 / 59
58. const member
class A {
public:
const int i;
A(int i_) : i(i_) {}
};
David Barina C/C++ tricks April 13, 2018 55 / 59
59. const member
class A {
public:
const int i;
A(int i_) : i(i_) {}
A& operator =( const A& a) {
i = a.i;
return *this;
}
};
error: assignment of read-only member ‘A::i’
David Barina C/C++ tricks April 13, 2018 56 / 59
60. const member
class A {
public:
const int i;
A(int i_) : i(i_) {}
A& operator =( const A& a) {
return *new(this) A(a);
}
};
A a(3);
a = A(4);
std:: cout << a.i << std:: endl; /* UB */
David Barina C/C++ tricks April 13, 2018 57 / 59
61. const member
class A {
public:
const int i;
A(int i_) : i(i_) {}
A& operator =( const A& a) {
return *new(this) A(a);
}
};
A a(3);
std:: cout << (a = A(4)).i << std:: endl;
David Barina C/C++ tricks April 13, 2018 58 / 59
62. const member (C++17)
class A {
public:
const int i;
A(int i_) : i(i_) {}
A& operator =( const A& a) {
return *new(this) A(a);
}
};
A a(3);
a = A(4);
std:: cout << std:: launder (&a)->i << std:: endl;
David Barina C/C++ tricks April 13, 2018 59 / 59