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.