Arduino icon indicating copy to clipboard operation
Arduino copied to clipboard

Variadic print

Open cousteaulecommandant opened this issue 8 years ago • 4 comments

Allows combining multiple arguments into a single call to Print::print[ln], like Serial.print("Answer=", 66, HEX). This feature requires C++11 or newer to work, but if it is not available the old calls can still be used. This change is backwards compatible: print(42, 16) prints "2A" as always, not "4216" (the latter can still be achieved with print(42, "", 16) ). Many functions from Print.cpp have been removed and replaced by inline versions in Print.h, most notably the println(...) ones. This results in a simplified (and thus easier to maintain) Print.cpp and slightly smaller executables.

cousteaulecommandant avatar Jan 10 '17 00:01 cousteaulecommandant

Everything done, thanks for the feedback!

As requested via IRC, here's an example sketch for testing backwards compatibility: https://gist.github.com/cousteaulecommandant/3083c33cc83497d05e1fa12ae8cfaf17#file-example_backwards_compat-ino

As can be seen, the resulting size is slightly smaller with the new code. However, some examples show a huge improvement, such as this one, where using inlined functions implies creating only 3 functions and not 4: https://gist.github.com/cousteaulecommandant/3083c33cc83497d05e1fa12ae8cfaf17#file-example_println_inlining-ino On this other example, however, the resulting code is a few bytes larger, since it has to include several extra calls to println(void) that were formerly included in the previous call: https://gist.github.com/cousteaulecommandant/3083c33cc83497d05e1fa12ae8cfaf17#file-example_println_inlining_2-ino

Regarding documentation, the only feature that has been added is the variadic support (the other commits inside this PR are just optimizations or improvements on readability and maintainability), so there shouldn't be big changes in the documentation. In any case, the current documentation is still valid since these changes were designed to be backwards compatible.

cousteaulecommandant avatar Jan 10 '17 20:01 cousteaulecommandant

@cousteaulecommandant, I finally got around to having another look at this. As we discussed on IRC, I'd like to see how feasible it is to extend this to also support custom formatters and/or more formatting options. As a proof-of-concept I made https://github.com/matthijskooijman/Arduino/commit/a3f0e33d946cc94e98f43f83accbe48b6ab14e93 today, which allows passing custom "formatter" objects after a value to format (e.g. instead of HEX). I've found that to reliably do this, I needed to move the actual printing code into a (non-variadic) doPrint() method, so print() can just take care of the variadic arguments (using some template magic in check_type, in a way similar to std::enable_if, to decide whether a second argument is a formatter or just something to print). As an added advantage, it seems it is no longer needed to repeat the list of int-as-second-argument-for-base-formatting as variadic versions). It might make sense to move this change into your PR if it really ends up being needed.

I'm still not sure how to add formatting options (e.g. options to default or other formatters) and especially how to combine these, so that needs a bit more thought.

matthijskooijman avatar Jun 19 '17 16:06 matthijskooijman

Personally I don't think we should be putting too much effort into formatters for Print, since

  • Print is already quite complex,
  • something like Serial.print(Format(number, digits, base, etc)) would be easier to implement and understand, and (depending on how it's implemented) not only useful for Print but also String and other uses,
  • printf (#5938) might be a simpler solution for complex formatting (and if "%02X" is too scary for newbies, maybe a "printf formatter constructor class" could be developed).

In other words, if complex and extensible formatters end up being added, I'd go for functions that return a Printable or a String rather than arguments to Print::print, as they would be much easier to implement and document, and move the formatting problem somewhere else.

(Serial.print(number, HEX) et al would need to be kept for backwards compatibility, but I would avoid going in that direction for new formatting features.)

cousteaulecommandant avatar Jun 21 '17 11:06 cousteaulecommandant

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Apr 09 '21 13:04 CLAassistant