Best Way to Reduce Overloading when Casting is Sufficient in C++ -


the avr-gcc compiler offers f() macro way define strings in statements , place strings in program memory. strings end being of type __flashstringhelper, however, , error if try pass them functions expect "const char *".

i can cast each 1 , code function. example code work:

int16_t lt_printf(const char *format, ...); lt_printf((const char *)f("testing!\r\n")); 

i can define overload function nothing receive __flashstringhelper , turn (const char *). works:

int16_t lt_printf(const __flashstringhelper *format, ...); lt_printf(f("testing!\r\n")); 

the second solution executes less efficiently first, @ least don't have hundreds of casts in code more.

is there way eliminate casts inside every function call, still not need overload function?

edited add more examples build (not of examples i'd do...i'm interested in pointer const __flashstringhelper):

typedef struct {   char test_string[20]; } test_struct_type; const test_struct_type progmem test_struct = {"struct testing!\r\n"}; const uint8_t progmem test_array[] = {'a', 'r', 'r', 'a', 'y', ' ', 't', 'e', 's', 't', 'i', 'n', 'g', '!', '\r', '\n', null}; const char progmem test_string[] = {"test testing!\r\n"};  void test() {   lt_printf(test_string);                       // doesn't need cast    lt_printf((const char *)f("f testing!\r\n")); // these need cast   lt_printf((const char *)&test_struct);   lt_printf((const char *)test_array);    lt_printf((pgm_p)f("f testing!\r\n"));        // cleaner cast   lt_printf((pgm_p)&test_struct);   lt_printf((pgm_p)test_array); } 

this results in output:

test testing! f testing! struct testing! array testing! f testing! struct testing! array testing! 

  lt_printf(test_string);                       // doesn't need cast   lt_printf((const char *)f("f testing!\r\n")); // these need cast   lt_printf((const char *)&test_struct); 

you can't cast away different data type , expect work. presuming test_string works expects print ram , not progmem in separate address space.

the simple solution in case derive class lt_printf in (whatever is) print , print, println etc. work.

for example, have library prints i2c lcd. derive print this:

class i2c_graphical_lcd_display : public print 

now class has implement write in class (ie. writing single byte) , print class takes care of rest: both writing ram , progmem via f() macro.

my answer doesn't address how printf work, although @ this.

you might better off looking @ streaming library lets stream output in c++ style, rather using printf-style outputting.


here simple way of implementing printf (however ram only) adding couple of helper functions:

int getchar (file *fp)   {   while (!(serial.available()));   return (serial.read());   }  // end of getchar  int putchar (char c, file *fp)   {   serial.write (c);   return c;   }  // end of putchar  void setup ()   {   serial.begin(115200);   fdevopen (putchar, getchar);   }  // end of setup  void loop ()   {   int temp = 30;    printf ("the temperature %d degrees c.\n", temp);   delay (100);   }  // end of loop 

fdevopen tells standard io library how , put characters. in particular case using serial, serial1 or softwareserial, etc.


if want use progmem constants (ie. f()) think easiest use streaming library. eg.

#include <streaming.h>  void setup ()   {   serial.begin (115200);   }  // end of setup  void loop ()   {   int temp = 30;       serial << f("the temperature ") << temp << f(" degrees c") << endl;   delay (100);   }  // end of loop 

that more compact, , saves ram using f() macro. it's pretty readable too.


Comments

Popular posts from this blog

gridview - Yii2 DataPorivider $totalSum for a column -

java - Suppress Jboss version details from HTTP error response -

Sass watch command compiles .scss files before full sftp upload -