Scientific Computing

C macro __CLASSIC_C__

The C macro __CLASSIC_C__ is defined when the compiler is in pre-ANSI (K&R) mode. This is a rather uncommon scenario. It might be used in retrocomputing with very old and unmaintained compilers such as the 1990s Bruce Evans’ C compiler (bcc).

#include <stdio.h>

int main() {

#if defined(__CLASSIC_C__)
  printf("K&R C\n");
#elif defined(__STDC__)
  printf("ANSI C\n");
#else
  printf("Unknown C\n");
#endif

return 0;
}

Reference: Compiler Macros wiki

Windows Command Prompt instant error on open

A botched program install, upgrade, or uninstall such as Anaconda Python can make a Windows registry mis-entry that causes many commands to fail. Simply trying to run “cmd.exe” COMSPEC instantly fails with:

& was unexpected at this time

or

Process exited with code 1

If this message occurs when just opening a new Command Prompt window, the problem may be in the Windows Registry. Check Registry Editor values:

HKCU\Software\Microsoft\Command Processor\AutoRun

and

HKLM\Software\Microsoft\Command Processor\AutoRun

Example 1

A system had a bad Autorun value:

if exist

This was corrected by emptying the Autorun value (or deleting the Autorun key).

Example 2

A system had a bad Autorun value:

if exist & if exist "%USERPROFILE%\miniconda3\condabin\conda_hook.bat" "%USERPROFILE%\miniconda3\condabin\conda_hook.bat"

It was fixed by correcting to:

if exist "%USERPROFILE%\miniconda3\condabin\conda_hook.bat" "%USERPROFILE%\miniconda3\condabin\conda_hook.bat"

C++ nodiscard attribute

C++17 and C23 added the [[nodiscard]] attribute to indicate that the result of a function call should not be ignored. Use care not to overspecify [[nodiscard]] on functions that are not intended to be used in a way that requires the result to be used, as this can make nuisance warnings.

Example: annotate function declaration in the header file with [[nodiscard]] attribute.

[[nodiscard]] int one();
int one() { return 1; }

GNU Data Language (GDL) GUI

GNU Data Language (GDL) can use GDLDE Workbench GUI for graphical development.

Download and install GDL.

  • Windows: installer includes GDLDE Workbench: gdlsetup-Windows-x86_64-standard.exe. Simply install and look in Windows Start menu for “GDL Workbench”.
  • macOS: use brew install gnudatalanguage
  • Ubuntu Linux: apt install gnudatalanguage

Download and extract GDLDE.

Install JDK

Install JDK by:

  • Windows: winget install Microsoft.OpenJDK.21 (find exact version by winget search Microsoft.OpenJDK).
  • macOS: brew install openjdk
  • Linux: apt install default-jdk

Restart Terminal, ensure that echo $JAVA_HOME or PowerShell echo $env:JAVA_HOME is not empty.

Eliminate Python __pycache__ directories

Python can put all Python .pyc cache files under one system-wide directory by the PYTHONPYCACHEPREFIX environment variable.

  • Windows: set environment variable PYTHONPYCACHEPREFIX to %TEMP%
  • Linux: in ~/.profile add export PYTHONPYCACHEPREFIX=${TMPDIR}
  • macOS: in ~/.zshrc add export PYTHONPYCACHEPREFIX=${TMPDIR}

Pycache .pyc files can be set to NOT write anywhere with the PYTHONDONTWRITEBYTECODE environment variable.

  • Windows: set environment variable PYTHONDONTWRITEBYTECODE to 1
  • Linux: in ~/.profile add export PYTHONDONTWRITEBYTECODE=1
  • macOS: in ~/.zshrc add export PYTHONDONTWRITEBYTECODE=1

Python 3.12 Apple App Store conflict

LWN.net reports on changes to Python 3.13 urllib standard library. It was deduced that Apple rejected Python 3.12 apps due to a string in the Python stdlib that was rejected, regardless of code execution. There naturally was some very good discussion linked to in the LWN.net article that illustrates the conflict between closed commercial platforms with great financial might and open source software. The Python 3.13 patch has already been merged. A pull request backport patch for Python 3.12 has also been created, and illustrates the clean nature of the patch and new configure flag.

Github Actions dynamic job environment variables

GitHub Actions jobs can dynamically set environment variables with job scope using a run: step to write the variable to an environment file.

Append to PATH: All job steps after the “run:” stanzas have the new PATH value “~/.local/bin” appended. Windows defaults to PowerShell.

- name: set Unix PATH
  if: runner.os != 'Windows'
  run: echo "${HOME}/.local/bin" >> $GITHUB_PATH

- name: set Windows PATH
  if: runner.os == 'Windows'
  run: echo "${HOME}/.local/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

Any environment variable can be set in this way. Example: set environment variables “CMAKE_INSTALL_PREFIX” and “CMAKE_PREFIX_PATH” to “~/libs” for the following job steps:

- name: set Unix
  if: runner.os != 'Windows'
  run: |
    echo "CMAKE_INSTALL_PREFIX=~/libs" >> $GITHUB_ENV
    echo "CMAKE_PREFIX_PATH=~/libs" >> $GITHUB_ENV

- name: set Windows
  if: runner.os == 'Windows'
  run: |
    echo "CMAKE_INSTALL_PREFIX=$HOME/libs" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    echo "CMAKE_PREFIX_PATH=$HOME/libs" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

Static environment variables in GitHub Actions

GitHub Actions environment variables have distinct scopes:

  • Workflow
  • Job
  • Step

It’s trivial to set static environment variables in each of these scopes. Dynamically setting environment variables is also possible.

Workflow

Set static workflow environment variables in GitHub Actions by using env: at the top level of a “.github/workflows/ci.yml” file like:

name: ci

env:
  CTEST_PARALLEL_LEVEL: 0
  CMAKE_BUILD_PARALLEL_LEVEL: 4
  CTEST_NO_TESTS_ACTION: error
  CMAKE_GENERATOR: Ninja
  CC: gcc

Job

Static job environment variables are set like:

jobs:

  base:
    runs-on: macos-latest

    strategy:
      matrix:
        cc: [gcc-13, clang]

    env:
      CMAKE_GENERATOR: Ninja
      CC: ${{ matrix.cc }}

Step

Set static step environment variables like:


    - run: cmake -B build
      env:
        CMAKE_GENERATOR: Ninja

Install MSYS2 on Windows

MinGW brings GNU compiler tools to Windows since the late 1990s. MSYS2 provides numerous developer tools including MinGW on Windows using pacman package manager.

Install MSYS2 by:

winget install MSYS2.MSYS2

Start the MSYS2 UCRT console in the Windows Start menu. Update MSYS2 to get the latest packages in the MSYS2 terminal. Run this command up to twice, until it says “nothing to do”.

pacman -Syu

To use GCC and other MSYS2 / MinGW64 programs from PowerShell without disrupting other compiler use, create file “gcc.ps1” containing:

$r="$Env:SystemDrive/msys64"
# The MSYS2 root directory is where MSYS2 is installed. It's CPU architecture dependent.
# for x86_64 CPU:
$r="$r/ucrt64"
# for ARM64 CPU:
#$r="$r/clangarm64"

$b="$r/bin"

$Env:CC="$b/gcc"
$Env:FC="$b/gfortran"
$Env:CXX="$b/g++"

# important to put UCRT first to avoid "collect2.exe: error: ld returned 116 exit status" and DLL Hell
$Env:Path = "$b;$Env:Path"

$Env:CMAKE_PREFIX_PATH="$r"

When it’s desired to use MSYS from a PowerShell prompt run “gcc.ps1”.

From MSYS2 command prompt, search for packages like:

pacman -Ss gcc

MSYS2 packages of interest for scientific computing include: gcc, gdb, gcc-fortran, clang, boost, lapack, scalapack, hdf5, make, pkgconf, aspell. Install packages with environment prefix “mingw-w64-ucrt-x86_64-” for x86_64 Windows applications for example Gfortran “mingw-w64-ucrt-x86_64-gcc-fortran”. On ARM64 Windows, use “mingw-w64-clang-aarch64-” environment prefix for example Clang “mingw-w64-clang-aarch64-clang”.

You may need to reorder directories in the Windows Path variable. For example GNU Octave may need to be moved lower in the Path list or removed from Path.

If you find that MSYS2 is using more 500 MB, try clearing the package cache of old package versions

pacman -Sc

The MSYS2 latest package update feed shows recently updated packages. The MSYS2 Install reference is also useful. PowerShell per-session variable set is useful to set CC, FC, CXX to single intended compiler to build systems.

Alternatives

As compared to Cygwin, MSYS2 works from the Windows Command Prompt or PowerShell. MSYS2 provides native Window binaries. Cygwin does not have a command-line package installer.

Windows Subsystem for Linux is strongly supported, but does not give Windows binaries unless cross-compiling.