C programming language

Standards not correctness are all that matters when the world is a PDP-11

notes

  • sharedlibraries can be packaged as executables
    • /lib64/ld-linux-x86-64.so.2 does this as does libQt5Core.so.5
    • Add -shared, -fpie, -Wl,--entry,main, -L. -l:hello -Wl,-rpath,., flags to gcc
      • ensure there is an exit() call in the entrypoint main
    • Add section for PT_INTERP
      • const char interp[] __attribute__ ((section(".interp"))) = PT_INTERP;
      • Add -D 'PT_INTERP="/lib64/ld-linux-x86-64.so.2"' to gcc
  • sizet for loop/index portability
  • errno.h and perror to print thread local state of errno
  • wchart
    • setlocale is global state across all threads
      • C locale is not UTF-8 there may be C.UTF-8 available
  • VLAs mandatory (again?) in C23
    • {} is valid 0 initializer to avoid memset of vla (could be 0 sized)
    • misunderstood as a 'stack' allocated array. Actual use is mainly for typing.
      • 'sufficently' smart compiler can expand/probe stack with heap allocation as needed to compute sizes based on default allocation sizes for the target compiled platforms.
      • ex. typedef int T[n] can be stack allocated T a or heap allocated T *a malloc(sizeof *a). Useful for matrix operations.
  • #embed add in C23 for including files as arrays (previously used xxd)
  • C11 added stdatomic.h
  • C11 added theads.h
  • C23 N2888 allows exact width integer types to exceed (u)intmax_t
  • C23 added constexpr
  • C23 adds nullptr constant
  • C23 adds auto typing
  • reserved names that start with to, is, etc (externally linked names are limited to ~36chars C99)
    • in standard library
    • begin with underscore and have external linkage
    • begin with an underscore followed by a capital letter or another underscore
    • begin with is or to followed by a lowercase letter
    • begin with str or wcs followed by a lowercase letter
    • begin with cr_
    • begin with atomic_ or memory_ followed by a lowercase letter
    • begin with cnd_, mtx_, thrd_ or tss_ followed by a lowercase letter
    • begin with int or uint and ending with _t
    • begin with E followed by a number or uppercase letter
    • begin with FE_ followed by an uppercase letter
    • begin with INT or UINT and ending with _MAX, _MIN, or _C
    • begin with LC_ or FP_ followed by an uppercase letter
    • begin with MATH_ followed by an uppercase letter
    • begin with SIG or SIG_ followed by an uppercase letter
    • begin with TIME_ or ATOMIC_ followed by an uppercase letter
    • gnu reserves names ending with _t, names begginning with mem then lowercase letter, names prefixed with any of d_ l_ F_ O_ S_ gr_ pw_ sa_ SA_ st_ tms_ c_ V I O TC, Names ending with _MAX, B followed by a number
// function to create signal handlers
#include <signal.h>
  void createSignalHandler() {
      struct sigaction SigInt; // declare signal action(s)
      memset(&SigInt, 0, sizeof(SigInt)); // clear the structure for SIGINT
      SigInt.sa_handler = signalHandler; // setup SIGINT as signalHandler
      sigemptyset(&SigInt.sa_mask);
      if (-1 == sigaction(SIGINT, &SigInt, NULL)) { // check errors
          // Error assigning SIGINT
      }
  }