Rix is the official package layer for Vix.cpp Browse packages
Skip to content

Print

This page explains the printing helpers provided by rix/debug.

The examples use the public Rix facade:

cpp
#include <rix.hpp>

and access Debug through:

cpp
rix.debug

Printing is useful for examples, quick checks, local diagnostics, small command-line tools, and development-time output.

For production application logs, prefer the Vix logging system.

Basic example

Create a file:

bash
mkdir -p ~/rix-debug-print
cd ~/rix-debug-print
touch print.cpp

Add:

cpp
#include <rix.hpp>

int main()
{
  rix.debug.print("Hello", "Rix");
  rix.debug.print("rows:", 3);
  rix.debug.print("ready:", true);

  rix.debug.eprint("stderr:", "example error output");

  rix.debug.dprint("debug:", "only useful while developing");

  return 0;
}

Run it:

bash
vix run print.cpp

If Rix is not available yet for single-file usage:

bash
vix install -g rix/rix
vix run print.cpp

Expected output

Standard output should look like this:

txt
Hello Rix
rows: 3
ready: true

The eprint output is written to stderr.

The exact behavior of dprint depends on debug configuration and build mode.

rix.debug.print

Use print for normal development output:

cpp
rix.debug.print("Hello", "Rix");

print writes values separated by spaces and adds a trailing newline.

Example:

cpp
rix.debug.print("package:", "rix/debug");
rix.debug.print("version:", rix.debug.version());
rix.debug.print("count:", 3);

This is the most common print helper.

You can pass several values:

cpp
rix.debug.print("name:", "Ada", "language:", "C++");

Output:

txt
name: Ada language: C++

Each value is rendered and separated by a space.

cpp
rix.debug.print("Hello from rix/debug");

Output:

txt
Hello from rix/debug
cpp
rix.debug.print("rows:", 3);
rix.debug.print("port:", 8080);

Output:

txt
rows: 3
port: 8080
cpp
rix.debug.print("ready:", true);
rix.debug.print("failed:", false);

Output shape:

txt
ready: true
failed: false
cpp
const std::string package = "rix/debug";

rix.debug.print("package:", package, "enabled:", true);

Output:

txt
package: rix/debug enabled: true

rix.debug.eprint

Use eprint for error-style output:

cpp
rix.debug.eprint("error:", "something failed");

eprint writes to stderr.

This is useful for examples where an operation can fail:

cpp
auto auth = rix.auth.memory();

auto login = auth.login({
    "ada@example.com",
    "wrong-password"});

if (login.failed())
{
  const auto &error = login.error();

  rix.debug.eprint(
      "auth error:",
      rix.auth.error.to_string(error),
      error.message());

  return 1;
}

Use eprint for local diagnostics, not for production logging.

rix.debug.dprint

Use dprint for debug-only output:

cpp
rix.debug.dprint("debug value:", 42);

Use it when the message is only useful while developing.

Example:

cpp
const auto table = rix.csv.parse(
    "name,language\n"
    "Ada,C++\n");

rix.debug.dprint("parsed rows:", table.size());

rix.debug.sprint

Use sprint when you want the same rendering as print, but returned as a string.

cpp
const auto line = rix.debug.sprint("rows:", 3);

rix.debug.print(line);

Output:

txt
rows: 3

This is useful when you want to build a message before printing it, storing it, or passing it to another API.

Use print when you want values separated by spaces:

cpp
rix.debug.print("rows:", 3);

Use format when you want placeholder-based text:

cpp
const auto message =
    rix.debug.format("rows: {}", 3);

rix.debug.print(message);

Both are useful.

print is faster to write.

format gives you more control over the message shape.

Complete print example

cpp
#include <rix.hpp>

#include <string>

int main()
{
  const std::string package = "rix/debug";

  rix.debug.print("== print example ==");
  rix.debug.print("package:", package);
  rix.debug.print("ready:", true);
  rix.debug.print("items:", 4);

  const auto line =
      rix.debug.sprint("generated:", package);

  rix.debug.print(line);

  rix.debug.eprint("stderr example:", "local diagnostic");

  return 0;
}

Run it:

bash
vix run print.cpp

Expected standard output:

txt
== print example ==
package: rix/debug
ready: true
items: 4
generated: rix/debug

rix.debug.print is useful when working with rix/csv.

cpp
#include <rix.hpp>

int main()
{
  const auto table = rix.csv.parse(
      "name,language\n"
      "Ada,C++\n"
      "Gaspard,Vix\n");

  rix.debug.print("rows:", table.size());

  for (const auto &row : table)
  {
    rix.debug.print("fields:", row.size());
  }

  return 0;
}

Run:

bash
vix run print.cpp

eprint is useful for Auth examples.

cpp
#include <rix.hpp>

int main()
{
  auto auth = rix.auth.memory();

  auto login = auth.login({
      "ada@example.com",
      "wrong-password"});

  if (login.failed())
  {
    const auto &error = login.error();

    rix.debug.eprint(
        "auth error:",
        rix.auth.error.to_string(error),
        error.message());

    return 1;
  }

  return 0;
}

Do not print authentication secrets in production.

Avoid printing:

txt
plain-text passwords
password hashes
session ids
raw token values

eprint is useful when a PDF operation fails.

cpp
#include <rix.hpp>

int main()
{
  auto doc = rix.pdf.document();

  auto &page = doc.add_page();

  page.text(
      page.x_left(),
      page.y_top(),
      "Hello from rix.pdf");

  auto saved = rix.pdf.save(doc, "");

  if (saved.failed())
  {
    rix.debug.eprint(
        "pdf error:",
        rix.pdf.error.to_string(saved.error()),
        saved.error().message());

    return 1;
  }

  rix.debug.print("created:", "example.pdf");

  return 0;
}

Use in a Vix project

Create a Vix application:

bash
vix new debug-print --app
cd debug-print

Add Rix:

bash
vix add rix/rix
vix install

In vix.app, make sure Rix is listed under deps:

txt
deps = [
  "rix/rix",
]

A small vix.app can look like this:

txt
name = "debug-print"
type = "executable"
standard = "c++20"
output_dir = "bin"

sources = [
  "src/main.cpp",
]

include_dirs = [
  "include",
  "src",
]

deps = [
  "rix/rix",
]

packages = [
  "vix",
]

links = [
  "vix::vix",
]

Then use Debug in src/main.cpp:

cpp
#include <rix.hpp>

int main()
{
  rix.debug.print("Hello", "Rix");
  rix.debug.eprint("stderr:", "example");

  return 0;
}

Build and run:

bash
vix build
vix run

Single-file usage

For small scripts, examples, and experiments:

bash
vix run print.cpp

If Rix is installed globally for single-file usage:

bash
vix install -g rix/rix
vix run print.cpp

For project usage, prefer:

bash
vix add rix/rix
vix install

and keep the dependency in vix.app:

txt
deps = [
  "rix/rix",
]

Use only Debug with the facade

If you want the rix.* facade style but only want Debug mounted, define the feature macro before including rix.hpp:

cpp
#define RIX_ENABLE_DEBUG
#include <rix.hpp>

int main()
{
  rix.debug.print("Hello", "Rix");
  return 0;
}

When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.

Use the independent package

For independent usage, install:

bash
vix add rix/debug
vix install

In vix.app:

txt
deps = [
  "rix/debug",
]

Then include the independent package header:

cpp
#include <rix/debug.hpp>

Use this style when a project only needs Debug and does not need the full unified Rix facade.

For most application documentation, prefer:

cpp
#include <rix.hpp>

Logging note

Printing is not the same as production logging.

Use rix.debug.print, rix.debug.eprint, rix.debug.dprint, and rix.debug.sprint for:

txt
examples
local diagnostics
small tools
tests
quick checks
documentation snippets

For real application logs, prefer the Vix logging system.

Use this rule:

txt
rix.debug -> simple development output
Vix logging -> production logs and runtime observability

Common mistakes

Using print as production logging

rix.debug.print is for development output and examples.

For services and deployed applications, use the Vix logging system.

Printing secrets

Do not print:

txt
plain-text passwords
password hashes
session ids
raw token values

This matters especially when using rix/auth.

Expecting print to format placeholders

print does not replace {} placeholders.

Wrong:

cpp
rix.debug.print("Package: {}", "rix/debug");

This prints the values separated by spaces.

Use format when you want placeholder replacement:

cpp
rix.debug.print(
    rix.debug.format("Package: {}", "rix/debug"));

Forgetting deps

For a Vix project, do not put Rix packages in packages.

Use:

txt
deps = [
  "rix/rix",
]

packages is for CMake package discovery.

deps is for Vix Registry packages.

What you should remember

Print values:

cpp
rix.debug.print("Hello", "Rix");

Print to stderr:

cpp
rix.debug.eprint("error:", "message");

Debug-only print:

cpp
rix.debug.dprint("debug:", 42);

Build printed output as a string:

cpp
auto line = rix.debug.sprint("rows:", 3);

Use format when you need placeholders:

cpp
auto message = rix.debug.format("Package: {}", "rix/debug");

For a Vix project, install Rix:

bash
vix add rix/rix
vix install

and use:

txt
deps = [
  "rix/rix",
]

Prefer Vix logging for real application logs.

Next step

Learn formatting.

Next: Formatting

Released under the MIT License.