C/C++ tricks
David Barina
April 13, 2018
David Barina C/C++ tricks April 13, 2018 1 / 59
Duff’s device
switch (count % 8) {
case 0: do { *to = *from ++;
case 7: *to = *from ++;
case 6: *to = *from ++;
case 5: *to = *from ++;
case 4: *to = *from ++;
case 3: *to = *from ++;
case 2: *to = *from ++;
case 1: *to = *from ++;
} while (( count -= 8) > 0);
}
David Barina C/C++ tricks April 13, 2018 2 / 59
[] operator
const char *a = "0123456789 abcdef";
int i = ...;
char digit = a[i];
char digit = *(a+i);
David Barina C/C++ tricks April 13, 2018 3 / 59
[] operator
const char *a = "0123456789 abcdef";
int i = ...;
char digit = a[i];
char digit = *(a+i);
char digit = i[a];
David Barina C/C++ tricks April 13, 2018 4 / 59
Swap algorithm
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap(int *a, int *b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
David Barina C/C++ tricks April 13, 2018 5 / 59
--> operator
int x = 10;
while( x --> 0 )
while( 0 <-- x )
while( 0 <---- x )
David Barina C/C++ tricks April 13, 2018 6 / 59
Catching exceptions in initializer lists
struct A {
A() : b() { ... }
B b;
};
A() : b() {
try {
...
} catch (...) {
...
}
}
David Barina C/C++ tricks April 13, 2018 7 / 59
Catching exceptions in initializer lists
struct A {
A() : b() { ... }
B b;
};
A() try : b() {
...
} catch (...) {
...
}
David Barina C/C++ tricks April 13, 2018 8 / 59
Namespace aliases
namespace foo {
namespace bar {
namespace baz {
int qux = 42;
}
}
}
namespace fbz = foo::bar::baz;
std:: cout << fbz::qux << ’n’;
David Barina C/C++ tricks April 13, 2018 9 / 59
Namespace aliases
#if THREADS_ARE_SUPPORTED_ON_THE_PLATFORM
namespace lib = project ::lib:: impl_with_threads ;
#else
namespace lib = project ::lib:: impl_wout_threads ;
#endif
David Barina C/C++ tricks April 13, 2018 10 / 59
Storage class specifiers
typedef int type;
int typedef type;
// static , extern
David Barina C/C++ tricks April 13, 2018 11 / 59
Integer overflow
for(char c = 100; c > 0; c++)
printf("%in", (int)c);
David Barina C/C++ tricks April 13, 2018 12 / 59
Integer promotion
char c = ’X’;
cout << c;
David Barina C/C++ tricks April 13, 2018 13 / 59
Integer promotion
char c = ’X’;
cout << c;
cout << +c;
David Barina C/C++ tricks April 13, 2018 14 / 59
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
Polyglot
if( sizeof(’a’) == sizeof(char) )
{
// compiled with C++
}
else
{
// compiled with C
}
David Barina C/C++ tricks April 13, 2018 16 / 59
Polyglot
#define R(U) sizeof(U"a"[0])
if( R("") == 4 )
{
// C++11 or newer
}
else
{
// C++03 or older
}
David Barina C/C++ tricks April 13, 2018 17 / 59
Polyglot
if( 2 // **/2
== 2 )
{
if( R("") == 4 )
{
// C11 or newer
}
else
{
// C99
}
}
else
{
// C90
}
David Barina C/C++ tricks April 13, 2018 18 / 59
Named loops
David Barina C/C++ tricks April 13, 2018 19 / 59
Named loops
outer: for( ... )
{
inner: for( ... )
{
...
goto outer;
}
}
David Barina C/C++ tricks April 13, 2018 20 / 59
Named loops
for( ... )
{
for( ... )
{
...
goto after;
}
}
after :;
David Barina C/C++ tricks April 13, 2018 21 / 59
Named loops
if( 0 )
after :;
else
for( ... )
{
for( ... )
{
...
goto after;
}
}
David Barina C/C++ tricks April 13, 2018 22 / 59
Named loops
[](){
for( ... )
{
for( ... )
{
...
return;
}
}
}();
David Barina C/C++ tricks April 13, 2018 23 / 59
Copy-and-swap
class dumb_array
{
public:
dumb_array(std:: size_t size = 0);
dumb_array(const dumb_array& other );
~dumb_array ();
private:
std:: size_t mSize;
int* mArray;
};
David Barina C/C++ tricks April 13, 2018 24 / 59
Copy-and-swap
dumb_array& operator =( const dumb_array& other)
{
if (this != &other) // (1)
{
delete [] mArray; // (2)
mArray = nullptr; // (2)
mSize = other.mSize; // (3)
mArray = mSize ? new int[mSize]
: nullptr; // (3)
std:: copy(other.mArray ,
other.mArray + mSize ,
mArray ); // (3)
}
return *this;
}
David Barina C/C++ tricks April 13, 2018 25 / 59
Copy-and-swap
friend void swap(dumb_array& first ,
dumb_array& second) // nothrow
{
using std:: swap;
swap(first.mSize , second.mSize );
swap(first.mArray , second.mArray );
}
dumb_array& operator =( dumb_array other) // (1)
{
swap (*this , other ); // (2)
return *this;
}
David Barina C/C++ tricks April 13, 2018 26 / 59
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
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
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
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
Integer overflow
int a = /* something */;
int b = /* something */;
a += b;
if( a < 0 ) {
/* ... */
}
David Barina C/C++ tricks April 13, 2018 29 / 59
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
Integer overflow
int a = /* something */;
int b = /* something */;
if( /* test */ ) {
/* ... */
}
a += b;
David Barina C/C++ tricks April 13, 2018 31 / 59
Integer overflow
C
#include <limits.h>
CHAR_MIN , SHRT_MIN , INT_MIN , LONG_MIN
CHAR_MAX , SHRT_MAX , INT_MAX , LONG_MAX
C++
#include <limits >
std:: numeric_limits <T>:: min()
std:: numeric_limits <T>:: max()
David Barina C/C++ tricks April 13, 2018 32 / 59
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
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
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
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
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
Implicit type conversion
int a = 5;
int b = a; /* <--- */
David Barina C/C++ tricks April 13, 2018 37 / 59
Implicit type conversion
int a = 5;
int b = a; /* nothing interesting */
David Barina C/C++ tricks April 13, 2018 38 / 59
Implicit type conversion
char a = 5;
int b = a; /* <--- */
David Barina C/C++ tricks April 13, 2018 39 / 59
Implicit type conversion
char a = 5;
int b = a; /* implicit type conversion */
David Barina C/C++ tricks April 13, 2018 40 / 59
Implicit type conversion
int a = 5;
char b = a; /* implicit type conversion */
David Barina C/C++ tricks April 13, 2018 41 / 59
Implicit type conversion
int a = 300;
char b = a; /* alter a value */
David Barina C/C++ tricks April 13, 2018 42 / 59
Implicit type conversion
int i = -1;
unsigned int u = i; /* change the sign */
David Barina C/C++ tricks April 13, 2018 43 / 59
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
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
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
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
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
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
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
Explicit type conversion (cast notation)
-Wold-style-cast
warning: use of old-style cast
David Barina C/C++ tricks April 13, 2018 51 / 59
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
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
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
const member
class A {
public:
const int i;
A(int i_) : i(i_) {}
};
David Barina C/C++ tricks April 13, 2018 55 / 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
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
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
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

C/C++ tricks

  • 1.
    C/C++ tricks David Barina April13, 2018 David Barina C/C++ tricks April 13, 2018 1 / 59
  • 2.
    Duff’s device switch (count% 8) { case 0: do { *to = *from ++; case 7: *to = *from ++; case 6: *to = *from ++; case 5: *to = *from ++; case 4: *to = *from ++; case 3: *to = *from ++; case 2: *to = *from ++; case 1: *to = *from ++; } while (( count -= 8) > 0); } David Barina C/C++ tricks April 13, 2018 2 / 59
  • 3.
    [] operator const char*a = "0123456789 abcdef"; int i = ...; char digit = a[i]; char digit = *(a+i); David Barina C/C++ tricks April 13, 2018 3 / 59
  • 4.
    [] operator const char*a = "0123456789 abcdef"; int i = ...; char digit = a[i]; char digit = *(a+i); char digit = i[a]; David Barina C/C++ tricks April 13, 2018 4 / 59
  • 5.
    Swap algorithm void swap(int*a, int *b) { int temp = *a; *a = *b; *b = temp; } void swap(int *a, int *b) { *a ^= *b; *b ^= *a; *a ^= *b; } David Barina C/C++ tricks April 13, 2018 5 / 59
  • 6.
    --> operator int x= 10; while( x --> 0 ) while( 0 <-- x ) while( 0 <---- x ) David Barina C/C++ tricks April 13, 2018 6 / 59
  • 7.
    Catching exceptions ininitializer lists struct A { A() : b() { ... } B b; }; A() : b() { try { ... } catch (...) { ... } } David Barina C/C++ tricks April 13, 2018 7 / 59
  • 8.
    Catching exceptions ininitializer lists struct A { A() : b() { ... } B b; }; A() try : b() { ... } catch (...) { ... } David Barina C/C++ tricks April 13, 2018 8 / 59
  • 9.
    Namespace aliases namespace foo{ namespace bar { namespace baz { int qux = 42; } } } namespace fbz = foo::bar::baz; std:: cout << fbz::qux << ’n’; David Barina C/C++ tricks April 13, 2018 9 / 59
  • 10.
    Namespace aliases #if THREADS_ARE_SUPPORTED_ON_THE_PLATFORM namespacelib = project ::lib:: impl_with_threads ; #else namespace lib = project ::lib:: impl_wout_threads ; #endif David Barina C/C++ tricks April 13, 2018 10 / 59
  • 11.
    Storage class specifiers typedefint type; int typedef type; // static , extern David Barina C/C++ tricks April 13, 2018 11 / 59
  • 12.
    Integer overflow for(char c= 100; c > 0; c++) printf("%in", (int)c); David Barina C/C++ tricks April 13, 2018 12 / 59
  • 13.
    Integer promotion char c= ’X’; cout << c; David Barina C/C++ tricks April 13, 2018 13 / 59
  • 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
  • 17.
    Polyglot #define R(U) sizeof(U"a"[0]) if(R("") == 4 ) { // C++11 or newer } else { // C++03 or older } David Barina C/C++ tricks April 13, 2018 17 / 59
  • 18.
    Polyglot if( 2 //**/2 == 2 ) { if( R("") == 4 ) { // C11 or newer } else { // C99 } } else { // C90 } David Barina C/C++ tricks April 13, 2018 18 / 59
  • 19.
    Named loops David BarinaC/C++ tricks April 13, 2018 19 / 59
  • 20.
    Named loops outer: for(... ) { inner: for( ... ) { ... goto outer; } } David Barina C/C++ tricks April 13, 2018 20 / 59
  • 21.
    Named loops for( ...) { for( ... ) { ... goto after; } } after :; David Barina C/C++ tricks April 13, 2018 21 / 59
  • 22.
    Named loops if( 0) after :; else for( ... ) { for( ... ) { ... goto after; } } David Barina C/C++ tricks April 13, 2018 22 / 59
  • 23.
    Named loops [](){ for( ...) { for( ... ) { ... return; } } }(); David Barina C/C++ tricks April 13, 2018 23 / 59
  • 24.
    Copy-and-swap class dumb_array { public: dumb_array(std:: size_tsize = 0); dumb_array(const dumb_array& other ); ~dumb_array (); private: std:: size_t mSize; int* mArray; }; David Barina C/C++ tricks April 13, 2018 24 / 59
  • 25.
    Copy-and-swap dumb_array& operator =(const dumb_array& other) { if (this != &other) // (1) { delete [] mArray; // (2) mArray = nullptr; // (2) mSize = other.mSize; // (3) mArray = mSize ? new int[mSize] : nullptr; // (3) std:: copy(other.mArray , other.mArray + mSize , mArray ); // (3) } return *this; } David Barina C/C++ tricks April 13, 2018 25 / 59
  • 26.
    Copy-and-swap friend void swap(dumb_array&first , dumb_array& second) // nothrow { using std:: swap; swap(first.mSize , second.mSize ); swap(first.mArray , second.mArray ); } dumb_array& operator =( dumb_array other) // (1) { swap (*this , other ); // (2) return *this; } David Barina C/C++ tricks April 13, 2018 26 / 59
  • 27.
    Member call onnull 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 onnull 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 onnull 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 onnull 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
  • 34.
    Integer overflow C #include <limits.h> CHAR_MIN, SHRT_MIN , INT_MIN , LONG_MIN CHAR_MAX , SHRT_MAX , INT_MAX , LONG_MAX C++ #include <limits > std:: numeric_limits <T>:: min() std:: numeric_limits <T>:: max() David Barina C/C++ tricks April 13, 2018 32 / 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
  • 40.
    Implicit type conversion inta = 5; int b = a; /* <--- */ David Barina C/C++ tricks April 13, 2018 37 / 59
  • 41.
    Implicit type conversion inta = 5; int b = a; /* nothing interesting */ David Barina C/C++ tricks April 13, 2018 38 / 59
  • 42.
    Implicit type conversion chara = 5; int b = a; /* <--- */ David Barina C/C++ tricks April 13, 2018 39 / 59
  • 43.
    Implicit type conversion chara = 5; int b = a; /* implicit type conversion */ David Barina C/C++ tricks April 13, 2018 40 / 59
  • 44.
    Implicit type conversion inta = 5; char b = a; /* implicit type conversion */ David Barina C/C++ tricks April 13, 2018 41 / 59
  • 45.
    Implicit type conversion inta = 300; char b = a; /* alter a value */ David Barina C/C++ tricks April 13, 2018 42 / 59
  • 46.
    Implicit type conversion inti = -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) classA { 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