---------------
Elem* next_elem();   // brak argumentw; zwraca warto typu Elem*
void exit(int);      // argument int; nic nie zwraca
double sqrt(double); // argument double; zwraca warto typu double
---------------
double s2 = sqrt(2);      // wywoanie funkcji sqrt() z argumentem double{2}
double s3 = sqrt("trzy"); // bd: funkcja sqrt() wymaga argumentu typu double
---------------
double f(int i, const Info&);  // typ: double(int,const Info&)
char& String::operator[](int); // typ: char& String::(int)
---------------
struct S {
    [[noreturn]] virtual inline auto f(const unsigned long int* const) -> void const noexcept;
};
---------------
void swap(int*, int*);    // deklaracja

void swap(int* p, int* q) // definicja
{
    int t = *p;
    *p = *q;
    *q = t;
}
---------------
void f(int);       // typ to void(int)
void f(const int); // typ to void(int)
---------------
void f(int x) { /* Tu mona modyfikowa x */ }
---------------
void f(const int x) { /* Tu nie mona modyfikowa x */ }
---------------
int& max(int& a, int& b, int& c); // zwraca referencj do najwikszej z wartoci a, b i c

int& max(int& x1, int& x2, int& x3)
{
    return (x1>x2)? ((x1>x3)?x1:x3) : ((x2>x3)?x2:x3);
}
---------------
void search(table* t, const char* key, const char*)
{
    // trzeci argument jest nieuywany
}
---------------
string to_string(int a);         // przedrostkowy typ zwrotny
auto to_string(int a) -> string; // przyrostkowy typ zwrotny
---------------
template<class T, class U>
auto product(const vector<T>& x, const vector<U>& y) -> decltype(x*y);
---------------
int f1() { }            // bd: nie zwraca wartoci
void f2() { }           // OK

int f3() { return 1; }  // OK
void f4() { return 1; } // bd: zwrot wartoci przez funkcj void

int f5() { return; }    // bd: brak wartoci zwrotnej
void f6() { return; }   // OK
---------------
int fac(int n)
{
    return (n > 1) ? n*fac(n-1) : 1;
}
---------------
int fac2(int n)
{
    if (n > 1)
        return n*fac2(n-1);
    return 1;
}
---------------
double f() { return 1; } // liczba 1 zostanie niejawnie przekonwertowana na double{1}
---------------
int*fp()
{
    int local = 1;
    //...
    return &local; // le
}
---------------
int& fr()
{
    int local = 1;
    //...
    return local; // le
}
---------------
void g(int* p);
void h(int* p)
{
    //...
    return g(p); // OK: rwnowane z g(p); return;
}
---------------
inline int fac(int n)
{
    return (n<2) ? 1 : n*fac(n-1);
}
---------------
constexpr int fac(int n)
{
    return (n>1) ? n*fac(n-1) : 1;
}

constexpr int f9 = fac(9); // warto musi zosta obliczona w czasie kompilacji
---------------
void f(int n)
{
    int f5 = fac(5);            // mona obliczy warto w czasie kompilacji
    int fn = fac(n);            // obliczane w czasie dziaania programu (n jest zmienn)
    
    constexpr int f6 = fac(6);  // warto musi zosta obliczona w czasie kompilacji
    constexpr int fnn = fac(n); // bd: nie mona zagwarantowa obliczenia w czasie kompilacji (n jest zmienn)

    char a[fac(4)];             // OK: granice tablicy musz by stae, a fac() jest constexpr
    char a2[fac(n)];            // bd: granice tablicy musz by stae, ale n jest zmienn

    //...
}
---------------
constexpr void bad1(int a) // bd: funkcja constexpr nie moe by void
{
    glob = a; // bd: efekt uboczny w funkcji constexpr
}

constexpr int bad2(int a)
{
    if (a>=0) return a; else return -a;   // bd: instrukcja if w funkcji constexpr
}

constexpr int bad3(int a)
{
    sum = 0;                              // bd: zmienna lokalna w funkcji constexpr
    for (int i=0; i<a; +=i) sum +=fac(i); // bd: ptla w funkcji constexpr
    return sum;
}
---------------
constexpr int ftbl[] { 1, 2, 3, 5, 8, 13 };

constexpr int fib(int n)
{
    return (n<sizeof(ftbl)/sizeof(*ftbl)) ? ftbl[n] : fib(n);
}
---------------
template<> class complex<float> {
public:
//...
    explicit constexpr complex(const complex<double>&);
    //...
};
---------------
constexpr complex<float> z {2.0};
---------------
constexpr const int* addr(const int& r) { return &r; } // OK
---------------
static const int x = 5;
constexpr const int* p1 = addr(x); // OK
constexpr int xx =*p1;             // OK

static int y;
constexpr const int* p2 = addr(y); // OK
constexpr int yy =*y;              // bd: prba odczytu zmiennej

constexpr const int*tp = addr(5);  // bd: adres obiektu tymczasowego
---------------
constexpr int check(int i)
{
    return (low<=i && i<high) ? i : throw out_of_range();
}

constexpr int low = 0;
constexpr int high = 99;

//...
constexpr int val = check(f(x,y,z));
---------------
[[noreturn]] void exit(int); // funkcja exit nie zwraca wartoci
---------------
void f(int a)
{
    while (a--) {
        static int n = 0; // jednorazowa inicjacja
        int x = 0;        // inicjacja a razy w kadym wywoaniu f()

        cout << "n == " << n++ << ", x == " << x++ << '\n';
    }
}

int main()
{
    f(3);
}
---------------
n==0,x==0
n==1,x==0
n==2,x==0
---------------
int fn(int n)
{
    static int n1 = n;         // OK
    static int n2 = fn(n-1)+1; // niezdefiniowane
    return n;
}
---------------
int* find(int* first, int* last, int v) // znajduje x w przedziale <first,last)
{
    while (first!=last && *first!=v)
        ++first;
    return first;
}

void g(int* p, int* q)
{
    int* pp = find(p,q,'x');
    //...
}
---------------
void f(int val, int& ref)
{
    ++val;
    ++ref;
}
---------------
void g()
{
    int i = 1;
    int j = 1;
    f(i,j);
}
---------------
void f(const Large& arg)
{
    // warto arg nie moe zosta zmieniona
    // (z wyjtkiem przypadku zastosowania jawnej konwersji typw - 11.5)
}
---------------
void g(Large& arg); // zaoenie, e g() modyfikuje arg
---------------
int strlen(const char*);                 // liczba znakw w acuchu w stylu C
char*strcpy(char* to, const char* from); // kopiowanie acucha w stylu C
int strcmp(const char*, const char*);    // porwnywanie acuchw w stylu C
---------------
float fsqrt(const float&); // funkcja pierw. w stylu Fortran przyjmujca referencj

void g(double d)
{
    float r = fsqrt(2.0f); // przekazanie referencji do obiektu tymczasowego zawierajcego 2.0f
    r = fsqr t(r);         // przekazanie referencji do r
    r = fsqr t(d);         // przekazanie referencji do obiektu tymczasowego zawierajcego static_cast<float>(d)
}
---------------
void update(float& i);

void g(double d, float r)
{
    update(2.0f); // bd: argument const
    update(r);    // przekazanie referencji do r
    update(d);    // bd: wymagana konwersja typw
}
---------------
void f(vector<int>&);        // referencja lewostronna jako argument (nie const)
void f(const vector<int>&);  // referencja lewostronna const jako argument
void f(vector<int>&&);       // referencja prawostronna jako argument

void g(vector<int>& vi, const vector<int>& cvi)
{
    f(vi);                   // wywoanie f(vector<int>&)
    f(vci);                  // wywoanie f(const vector<int>&)
    f(vector<int>{1,2,3,4}); // wywoanie f(vector<int>&&);
}
---------------
int strlen(const char*);

void f()
{
    char v[] = "Annemarie";
    int i = strlen(v);
    int j = strlen("Nicholas");
}
---------------
void odd(int* p);
void odd(int a[]);
void odd(int buf[1020]);
---------------
void compute1(int* vec_ptr, int vec_size); // jeden sposb
---------------
void f(int(&r)[4]);

void g()
{
    int a1[] = {1,2,3,4};
    int a2[] = {1,2};

    f(a1); // OK
    f(a2); // bd: nieprawidowa liczba elementw
}
---------------
template<class T, int N> void f(T(&r)[N])
{
    //...
}

int a1[10];
double a2[100];

void g()
{
    f(a1); // T jest int; N jest 10
    f(a2); // T jest double; N jest 100
}
---------------
const char*day[] = {
    "pon", "wt", "r", "czw", "pi", "sob", "nie"
};
---------------
template<class T>
void f1(initializer_list<T>);

struct S {
    int a;
    string s;
};
void f2(S);

template<class T, int N>
void f3(T (&r)[N]);

void f4(int);

void g()
{
    f1({1,2,3,4}); // T jest int, a initializer_list ma rozmiar 4
    f2({1,"MKS"}); // f2(S{1,"MKS"})
    f3({1,2,3,4}); // T jest int, a N jest 4
    f4({1});       // f4(int{1});
}
---------------
template<class T>
void f(initializer_list<T>);

struct S {
    int a;
    string s;
};
void f(S);

template<class T, int N>
void f(T (&r)[N]);

void f(int);

void g()
{
    f({1,2,3,4}); // T jest int, a initializer_list ma rozmiar 4
    f({1,"MKS"}); // wywouje f(S)
    f({1});       // T jest int, a initializer_list ma rozmiar 1
}
---------------
int printf(const char* ...);
---------------
printf("Witaj, wiecie!\n");
printf("Nazywam si %s %s\n", first_name , second_name);
printf("%d + %d = %d\n",2,3,5);
---------------
#include <cstdio>

int main()
{
    std::printf("My name is %s %s\n",2);
}
---------------
int fprintf(FILE*, const char*...); // z <cstdio>
int execl(const char*...);          // z nagwka UNIX
---------------
extern void error(int ...);
extern char* itoa(int, char[]); // int na alfabet

int main(int argc, char* argv[])
{
    switch (argc) {
    case 1:
        error(0,argv[0],nullptr);
        break;
    case 2:
        error(0,argv[0],argv[1],nullptr);
        break;
    default:
        char buffer[8];
        error(1,argv[0],"z",itoa(argc-1,buffer),"argumentami",nullptr);
    }
    // ...
}
---------------
#include <cstdarg>

void error(int severity ...) // severity i zakoczona zerem lista argumentw char*
{
    va_list ap;
    va_start(ap,severity);   // pocztek argumentw

    for (;;) {
        char* p = va_arg(ap,char*);
        if (p == nullptr) break;
        cerr << p << '';
    }

    va_end(ap);              // koniec argumentw

    cerr << '\n';
    if (severity) exit(severity);
}
---------------
void error(int severity, initializer_list<string> err)
{
    for (auto& s : err)
        cerr << s << ' ';
    cerr << '\n';
    if (severity) exit(severity);
}
---------------
switch (argc) {
case 1:
    error(0,{argv[0]});
    break;
case 2:
    error(0,{argv[0],argv[1]});
    break;
default:
    error(1,{argv[0],"z",to_string(argc-1),"argumentami"});
}
---------------
void error(int severity, const vector<string>& err) // prawie jak poprzednio
{
    for (auto& s : err)
        cerr << s << ' ';
    cerr << '\n';
    if (severity) exit(severity);
}

vector<string> arguments(int argc, char* argv[])    // pakowanie argumentw
{
    vector<string> res;
    for (int i = 0; i!=argc; ++i)
        res.push_back(argv[i]);
    return res
}

int main(int argc, char* argv[])
{
    auto args = arguments(argc,argv);
    error((args.size()<2)?0:1,args);
    // ...
}
---------------
class complex {
    double re, im;
public:
    complex(double r, double i) :re{r}, im{i} {} // tworzy liczb zespolon z dwch wartoci skalarnych
    complex(double r) :re{r}, im{0} {}           // tworzy liczb zespolon z jednej wartoci skalarnej
    complex() :re{0}, im{0} {}
    // domylna liczba zespolona: {0,0}
    //...
};
---------------
complex(double r, double i) :re{r}, im{i} {} // tworzy liczb zespolon z dwch wartoci skalarnych
complex(double r) :complex{2,0} {}           // tworzy liczb zespolon z jednej wartoci skalarnej
complex() :complex{0,0} {}                   // domylna liczba zespolona: {0,0}
---------------
complex(double r ={}, double i ={}) :re{r}, im{i} {} // tworzy liczb zespolon z dwch wartoci skalarnych
---------------
class X {
public:
    static int def_arg;
    void f(int =def_arg);
    //...
};

int X::def_arg = 7;

void g(X& a)
{
    a.f(); // moe f(7)
    a.def_arg = 9;
    a.f(); // f(9)
}
---------------
int f(int, int =0, char* =nullptr); // OK
int g(int =0, int =0, char*);       // bd
int h(int =0, int, char* =nullptr); // bd
---------------
int nasty(char*=nullptr);           // bd skadni
---------------
void f(int x = 7);
void f(int = 7);       // bd: nie mona powtrzy domylnego argumentu
void f(int = 8);       // bd: rne domylne argumenty

void g()
{
    void f(int x = 9); // OK: ta deklaracja zasania zewntrzn
    // ...
}
---------------
void print(int);         // drukuje warto typu int
void print(const char*); // drukuje acuch w stylu C
---------------
void print(double);
void print(long);

void f()
{
    print(1L);  // print(long)
    print(1.0); // print(double)
    print(1);   // bd niejednoznacznoci: print(long(1)) czy print(double(1))?
}
---------------
void print(int);
void print(const char*);
void print(double);
void print(long);
void print(char);

void h(char c, int i, short s, float f)
{
    print(c);       // dokadnie dopasowanie: wywoanie print(char)
    print(i);       // dokadnie dopasowanie: wywoanie print(int)
    print(s);       // promocja cakowitoliczbowa: wywoanie print(int)
    print(f);       // promocja float na double: print(double)

    print('a');     // dokadnie dopasowanie: wywoanie print(char)
    print(49);      // dokadnie dopasowanie: wywoanie print(int)
    print(0);       // dokadnie dopasowanie: wywoanie print(int)
    print("a");     // dokadnie dopasowanie: wywoanie print(const char*)
    print(nullptr); // promocja nullptr_t na const char*: wywoanie print(cost char*)
}
---------------
void print_int(int);
void print_char(char);
void print_string(const char*); // acuch w stylu C

void g(int i, char c, const char* p, double d)
{
    print_int(i);    // OK
    print_char(c);   // OK
    print_string(p); // OK

    print_int(c);    // OK? wywouje print_int(int(c)), drukuje liczb
    print_char(i);   // OK? wywouje print_char(char(i)), zawenie
    print_string(i); // bd
    print_int(d);    // OK? wywouje print_int(int(d)), zawenie
}
---------------
float sqrt(float);
double sqrt(double);

void f(double da, float fla)
{
    float fl = sqrt(da); // wywoanie sqrt(double)
    double d = sqrt(da); // wywoanie sqrt(double)
    fl = sqrt(fla);      // wywoanie sqrt(float)
    d = sqrt(fla);       // wywoanie sqrt(float)
}
void f(int);

void g()
{
    void f(double);
    f(1); // wywoanie f(double)
}
---------------
struct Base {
void f(int);
};

struct Derived : Base {
    void f(double);
};

void g(Derived& d)
{
    d.f(1); // wywoanie Derived::f(double);
}
---------------
int pow(int, int);
double pow(double, double);
complex pow(double, complex);
complex pow(complex, int);
complex pow(complex, complex);

void k(complex z)
{
    int i = pow(2,2);        // wywoanie pow(int,int)
    double d = pow(2.0,2.0); // wywoanie pow(double,double)
    complex z2 = pow(2,z);   // wywoanie pow(double,complex)
    complex z3 = pow(z,2);   // wywoanie pow(complex,int)
    complex z4 = pow(z,z);   // wywoanie pow(complex,complex)
}
---------------
void g()
{
    double d = pow(2.0,2); // bd: pow(int(2.0),2) czy pow(2.0,double(2))?
}
---------------
void f1(char);
void f1(long);

void f2(char*);
void f2(int*);

void k(int i)
{
    f1(i); // niejednoznaczne: f1(char) czy f1(long)?
    f2(0); // niejednoznaczne: f2(char*) czy f2(int*)?
}
---------------
inline void f1(int n) { f1(long(n)); }
---------------
f2(static_cast<int*>(0));
---------------
int area(int len, int wid)
/*
    Oblicza pole powierzchni prostokta

    Warunek wstpny: len i wid musz by dodatnie

    Warunek kocowy: warto zwrotna musi by dodatnia

    Warunek kocowy: warto zwrotna jest polem powierzchni prostokta o bokach len i wid
*/
{
    return len*wid;
}
---------------
void error(string s) { /*...*/ }
void (*efct)(string); // wskanik do funkcji pobierajcej acuch i nic nie zwracajcej

void f()
{
    efct = &error;    // efct wskazuje error
    efct("error");    // wywoanie error poprzez efct
}
---------------
void (*f1)(string) = &error; // OK, to samo co = error
void (*f2)(string) = error;  // OK, to samo co = &error

void g()
{
    f1("Vasa");              // OK, to samo co (*f1)("Vasa")
    (*f1)("Mary Rose");      // OK, to samo co f1("Mary Rose")
}
---------------
void (*pf)(string);     // wskanik do void(str ing)
void f1(string);        // void(string)
int f2(string);         // int(string)
void f3(int*);          // void(int*)

void f()
{
    pf = &f1;           // OK
    pf = &f2;           // bd: niepoprawny typ zwrotny
    pf = &f3;           // bd: niepoprawny typ argumentu

    pf("Hera");         // OK
    pf(1);              // bd: niepoprawny typ argumentu

    int i = pf("Zeus"); // bd: przypisanie void do int
}
---------------
using P1 = int(*)(int*);
using P2 = void(*)(void);

void f(P1 pf)
{
    P2 pf2 = reinterpret_cast<P2>(pf)
    pf2();                              // ryzyko powanych problemw
    P1 pf1 = reinterpret_cast<P1>(pf2); // konwersja pf2 na pierwotny typ
    int x = 7;
    int y = pf1(&x);                    // OK
    //...
}
---------------
using CFT = int(const void*, const void*);

void ssort(void*  base , size_t n, size_t sz, CFT cmp)
/*
    Sortuje n elementw wektora base w kolejnoci rosncej
    przy uyciu funkcji porwnywania wskazywanej przez cmp.
    Elementy s rozmiaru sz.

    Sortowanie Shella (Knuth, tom 3, str. 84)
*/
{
    for (int gap=n/2; 0<gap; gap/=2)
        for (int i=gap; i!=n; i++)
            for (int j=i-gap; 0<=j; j-=gap) {
                char* b = static_cast<char*>(base); // niezbdne rzutowanie
                char* pj = b+j*sz;                  // &base[j]
                char* pjg = b+(j+gap)*sz;           // &base[j+gap]
                if (cmp(pjg,pj)<0) {                // zamiana base[j] i base[j+gap]:
                    for (int k=0; k!=sz; k++) {
                        char temp = pj[k];
                        pj[k] = pjg[k];
                        pjg[k] = temp;
                    }
                }
            }
    }
---------------
struct User {
    const char* name;
    const char* id;
    int dept;
};

vector<User> heads = {
    "Ritchie D.M.", "dmr", 11271,
    "Sethi R.", "ravi", 11272,
    "Szymanski T.G.", "tgs", 11273,
    "Schryer N.L.", "nls", 11274,
    "Schryer N.L.", "nls", 11275,
    "Kernighan B.W.", "bwk", 11276
};

void print_id(vector<User>& v)
{
    for (auto& x : v)
        cout << x.name << '\t' << x.id << '\t' << x.dept << '\n';
}
---------------
int cmp1(const void* p, const void* q) // porwnuje acuchy name
{
    return strcmp(static_cast<const User*>(p)->name ,static_cast<const User*>(q)->name);
}

int cmp2(const void*p, const void*q)   // porwnuje liczby dept
{
    return static_cast<const User*>(p)->dept - static_cast<const User*>(q)->dept;
}
---------------
int cmp3(const User* p, const User* q) // porwnuje identyfikatory
{
    return strcmp(p->id,q->id);
}
---------------
int main()
{
    cout << "Szefowie w kolejnoci alfabetycznej:\n";
    ssort(heads,6,sizeof(User),cmp1);
    print_id(heads);
    cout << '\n';

    cout << "Szefowie w kolejnoci wg numeru wydziau:\n";
    ssort(heads,6,sizeof(User),cmp2);
    print_id(heads);
}
---------------
int main()
{
    cout << "Szefowie w kolejnoci alfabetycznej:\n";
    sort(heads.begin(), head.end(),
         [](const User& x, const User& y) { return x.name<y.name; }
    );
    print_id(heads);
    cout << '\n';

    cout << "Szefowie w kolejnoci wg numeru wydziau:\n";
    sor t(heads.begin(), head.end(),
         [](const User& x, const User& y) { return x.dept<y.dept; }
    );
    print_id(heads);
}
---------------
sort(heads,[](const User& x, const User& y) { return x.name<y.name; });
---------------
void f(int);
int f(char);
void (*pf1)(int) = &f;  // void f(int)
int (*pf2)(char) = &f;  // int f(char)
void (*pf3)(char) = &f; // bd: nie ma wersji void f(char)
---------------
void f(int) noexcept;
void g(int);
void (*p1)(int) = f;          // OK: ale opuszczamy wane informacje
void (*p2)(int) noexcept = f; // OK: zachowujemy informacj o noexcept
void (*p3)(int) noexcept = g; // bd: nie wiemy, czy g nie moe zgasza wyjtkw
---------------
using Pc = extern "C" void(int); // bd: specyfikacja czenia w aliasie
using Pn = void(int) noexcept;   // bd: noexcept w aliasie
---------------
#define NAZWA reszta wiersza
---------------
named = NAZWA
---------------
named = reszta wiersza
---------------
#define MAC(x,y) argument1: x argument2: y
---------------
expanded = MAC(foo bar, yuk yuk)
---------------
expanded = argument1: foo bar argument2: yuk yuk
---------------
#define PRINT(a,b) cout<<(a)<<(b)
#define PRINT(a,b,c) cout<<(a)<<(b)<<(c) /* Problem?: redefinicja, nie przecienie */

#define FAC(n) (n>1)?n*FAC(n-1):1        /* Problem: rekurencja */
---------------
#define CASE break;case
#define FOREVER for(;;)
---------------
#define PI 3.141593
#define BEGIN {
#define END }
---------------
#define SQUARE(a) a*a
#define INCR_xx (xx)++
---------------
int xx = 0;               // globalny licznik

void f(int xx)
{
    int y = SQUARE(xx+2); // y=xx+2*xx+2; to jest y=xx+(2*xx)+2
    INCR_xx;              // zwiksza argument xx (nie globaln zmienn xx)
}
---------------
#define MIN(a,b) (((a)<(b))?(a):(b))
---------------
int x = 1;
int y = 10;
int z = MIN(x++,y++);      // x ma warto 3; y ma warto 11
---------------
#define M2(a) something(a) /* Jaki mdry komentarz */
---------------
const int answer = 42;

template<class T>
inline const T& min(const T& a, const T& b)
{
    return (a<b)?a:b;
}
---------------
#define NAME2(a,b) a##b
int NAME2(hack,cah)();
---------------
int hackcah();
---------------
#define printx(x) cout << #x " = " << x << '\n';

int a = 7;
string str = "asdf";

void f()
{
    printx(a);   // cout << "a" << " = " << a << '\n';
    printx(str); // cout << "str" << " = " << str << '\n';
}
---------------
#undef X
---------------
#define EMPTY() std::cout<<"pusto\n"
EMPTY(); // drukuje "pusto\n"
EMPTY;   // bd: brak listy elementw do zamiany
---------------
#define err_print(...) fprintf(stderr,"Bd: %s %d\n", __VA_ARGS__)
err_print("Odpowied brzmi",54);
---------------
Bd: odpowied brzmi 54
---------------
#ifdef IDENTYFIKATOR
---------------
int f(int a
#ifdef arg_two
,int b
#endif
);
---------------
int f(int a
);
---------------
struct Call_info {
    Node* arg_one;
    Node* arg_two;
    //...
};
---------------
#define arg_two x
---------------
cout << __FUNC__ << "() w pliku " << __FILE__ << " w wierszu " << __LINE__ << "\n";
---------------
#pragma foo bar 666 foobar
