Notes

Cpp Concepts

Copy Constructors

#include<iostream>
using namespace std;

class Animal{
    Animal();   // Default constructor
    Animal(const Animal &a);    // Copy constructor
    Animal & operator = (const Animal & b); // copy operator
    ~Animal();  // destructor
}

Explicit conversion

int main(){
    int i='x'; //implicit conversion from char to asci int
    explicit int j='d'; // shows error, bcz declared as explicit variable and doesn't allow \
    implicit conversion
}

Smart pointers

Smart Pointers are used to help ensure that programs are free of memory and resource leaks and are exception-safe.

View more about this here


Lambda functions

[ capture clause ] (parameters) -> return-type  
{
   definition of method
}
int main(){
    int i=0;
    int x=[i](int &j=5) -> int {
        return j*i+5;
    }
}

Constants

const and constexpr both are used for declaring constant variables. But const keyword is not completely pure constant.

int getRandomNo()
{
  return rand() % 10;
}

int main()
{
    const int varB = getRandomNo();       // OK
    constexpr int varC = getRandomNo();   // not OK! compilation error

    return 0;
}

Explanation: Value of varB would not anymore compile time. While statement with varC will throw compilation error. The reason is constexpr will always accept a strictly compile-time value.


Conditional compilation

'''statements'''
#if
#else
#ifdef
#ifndef
#elif
#endif
#if defined(MACRO)
#if !defined(MACRO)

'''Example'''

#pragma once    // For including files only once; but can be fooled by symbolic links.
#ifndef __PROGRAM    // For including files only once
#define __PROGRAM

#ifndef CONDITIONAL_H_
    #define CONDITIONAL_H_

    #ifdef _FOO
        #define _NUMBER 47
    #else
        #define _NUMBER 2
    #endif
#endif

#endif

Format-Style print()

#include<format>
using namespace std;

constexpr void print(const string_view str_fmt, auto&&... args){
    fputs(vformat(str_fmt, make_format_args(args...)).cstr(), stdout);
}

int main(){
    int i=5;
    print("The value is {}\n",i); // This works exactly like printf( format( "{}\n", i ));
}

Output:

The value is 5

Concurrency


Name Mangling

Since C++ supports function overloading, additional information has to be added to function names (called Name mangling) to avoid conflicts in binary code.

int f(void) { return 1; }
 
int f(int) { return 0; }
 
void g(void) { int i = f(), j = f(0); }

Some C++ compilers may mangle the above names to the following,

int __f_v(void) { return 1; }
 
int __f_i(int) { return 0; }
 
void __g_v(void) { int i = __f_v(), j = __f_i(0); }



Handling C symbols when linking from C++
Note: C does not support function overloading, So, when we link a C code in C++, we have to make sure that name of a symbol is not changed.

In C, names may not be mangled as it doesn’t support function overloading. So how to make sure that name of a symbol is not changed when we link a C code in C++.

int printf(const char* format, ...);
 
int main()
{
    printf("Hello...");
    return 0;
}
Compiler Error:

In function `main’:
f84cc4ebaf5b87bb8c6b97bc54245486.cpp:(.text+0xf): undefined reference to `printf(char const*, …)’
collect2: error: ld returned 1 exit status

When some code is put in the extern “C” block, the C++ compiler ensures that the function names are un-mangled – that the compiler emits a binary file with their names unchanged, as a C compiler would do.

extern "C" {
int printf(const char* format, ...);
}
 
int main()
{
    printf("Hello...");
    return 0;
}

Therefore, all C style header files (stdio.h, string.h, etc) have their declarations in the extern “C” block.

#ifdef __cplusplus
extern "C" {
#endif
// Declarations of this file
#ifdef __cplusplus
}
#endif

GDB Debugger

The GNU Debugger (GDB) is a popular, free, and open-source debugger for C and C++ programs, which is widely used in Unix-like systems

Cpp Hacks

Fast I/O

auto init = []() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    return 'c';
}();