Skip to content

Use fixed-width integer types throughout - #23

Merged
theAndreas merged 4 commits into
mainfrom
fixed-width-types
Oct 30, 2026
Merged

theAndreas merged 4 commits into
mainfrom
fixed-width-types

Conversation

@theAndreas

Copy link
Copy Markdown
Owner

Builds on #22 (shift timing), which touches the same lines; until #22 is merged, its commits show here too. The commit of this PR is the last one, Use fixed-width integer types throughout.

What moved. int, unsigned, short and long are gone from src/, simulator/ and test/. An int is 16 bits on the Uno and 32 on the host, so the tests ran the library with other types than the board does. CLAUDE.md has the rule now, under "Integer types".

  • src/: the coordinates of setChar() and setSprite(), which may lie off the panel to the left, are int16_t, as is the column setText() counts up. Loop counters below 256 are byte, as elsewhere in the library. That is the public API's only change, and on the Uno int already is int16_t.
  • simulator/: ports uint16_t, times from millis() uint32_t, slots, rounds and modules uint8_t. SimulatorPanel::getIntensity() returns uint8_t, which the terminal casts to uint16_t before it goes into the stream; otherwise it would print as a char.
  • test/: the mock counts Frames and Errors in int32_t and holds its clock in milliseconds; the model takes uint16_t X, uint8_t Y; the tests follow.

Why byte stays. It is Arduino's name for uint8_t, already fixed, and the name sketches use; renaming 125 lines of the public API would change how every signature reads and nothing else.

What keeps its type, because an outside interface fixes it: argc and an index into argv; millis()/micros()/delay() in the mock, declared as the Arduino core declares them; strtoul() until its range is checked (narrowing first would let --port 4294967376 wrap to 80); POSIX file descriptors and setsockopt() options; size_t for container sizes.

Measured. 209 tests pass. On the Uno, Basics 3604 and ScrollText 3716 bytes of flash, 4 and 2 fewer than with int loop counters (the byte counters); RAM unchanged at 73 and 85. Both examples compile without warnings, arduino-lint is clean. Not run on hardware; nothing in the transfer code changed.

Every sketch timed shiftTask() itself: ScrollText with millis() and a
LastShift of its own, the README with delay(50). shiftTask() now takes
a step only when ShiftInterval has passed since the last one, so a
sketch calls it on every loop(). setShiftInterval() takes milliseconds
per column, as setSpeed in MD_Parola does; MAXMATRIX_SHIFT_INTERVAL_
INIT_VALUE starts it at 50, and 0 makes every call a step again.

The first step comes on the first call after setTextWithShift() or
setCharWithShift(): startShift() dates the last step one interval back.
A late call takes one step and counts on from there instead of catching
up, so that the text never jumps after loop() was held up.

The mock can hold its clock: Mock::setMillis() sets millis() until the
next reset(), and delay() then moves it on without waiting, so that a
step 50 ms on does not depend on how fast the host is. The library
tests set the interval to 0 in SetUp(), as they step the text with
every call; the timing has four tests of its own, which catch a first
step that waits, a late call that catches up, an off-by-one and no
timing at all.

Interval and last step are uint16_t and uint32_t: six bytes of RAM.
ScrollText drops its own LastShift and millis() check and sets the
interval with setShiftInterval(); the README calls shiftTask() on every
loop() without delay(50) and says how the interval works. keywords.txt
gets the two new functions, OIL item 23 says how it was built, and the
text that starts over by itself goes to item 12.

On the Uno, ScrollText is 3718 bytes of flash and 85 of RAM, against
3578 and 83: +112 in main, where the 32 bit check against millis() is
inlined at each call, +28 for the two new members in the constructor;
the sketch's own LastShift is gone from RAM. Basics, which does not
shift, is 3610 and 73 (+28 and +6).
int, unsigned, short and long are gone from src/, simulator/ and test/.
An int is 16 bits on the Uno and 32 on the host, so the tests ran the
library with other types than the board does.

In src/, the coordinates of setChar() and setSprite(), which may lie
off the panel to the left, are int16_t, as is the column setText()
counts up; loop counters below 256 are byte, as elsewhere in the
library. On the Uno an int is an int16_t, so nothing changes there:
Basics 3604 and ScrollText 3716 bytes of flash, 4 and 2 fewer than
with int loop counters; RAM unchanged.

In the simulator, ports are uint16_t, times from millis() uint32_t,
slots, rounds and modules uint8_t. SimulatorPanel::getIntensity()
returns a uint8_t, which the terminal casts to uint16_t before it goes
into the stream, or it would print as a char. The mock counts Frames
and Errors in int32_t and holds its clock in milliseconds.

The type stays where an outside interface fixes it: argc and an index
into argv, millis()/micros()/delay() as the Arduino core declares them,
strtoul() until its range is checked, POSIX file descriptors and
setsockopt() options, size_t for container sizes. byte stays as the
Arduino name for uint8_t. CLAUDE.md now has the rule.
@theAndreas
theAndreas merged commit d8228d9 into main Oct 30, 2026
3 checks passed
@theAndreas
theAndreas deleted the fixed-width-types branch October 30, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants