Print array of chars by F() makro - c++

To reduce the usage of SRAM on my Arduino I'd like to print some text via the F() makro:
void setup() {
char text[] = "i am just text";
if(Serial) {
Serial.println(F(text));
}
}
But this throws the following error
C:\Temp\Software\arduino-1.8.10\hardware\arduino\avr\cores\arduino/WString.h:38:74:
error: initializer fails to determine size of '__c'
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper*>(PSTR(string_literal)))
C:\Temp\Software\arduino-1.8.10\hardware\arduino\avr\cores\arduino/WString.h:38:74:
error: array must be initialized with a brace-enclosed initializer
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper*>(PSTR(string_literal)))
But I don't really understand how to fix this. Could someone please help me to Serial.println() the text variable via F()?

In your example, text is a mutable char[]. Moving that to flash would be problematic. Changing the mutable in runtime, text[0] = 'I';, would not work as promised. Use the macro with a const char* instead - and do it around the string literal you want flashed.
Try:
auto text = F("i am just text");
// or: auto text = FPSTR("i am just text");
// or: static const char text[] PROGMEM = "i am just a text";
Serial.println(text);
When passing it to a function, you could add an overload for const __FlashStringHelper* (like Print and Println has):
void debug(const __FlashStringHelper *txt) {
Serial.println(txt);
}
...
debug(text);
Disclamer: Untested

Related

Prober type for type "char text [100]" in class

I have the following but I can't figure out what I am doing wrong. I obviously have the wrong types in the argument definition but I can't figure out what the correct syntax would be.
dto.h
...
class Dto
{
public:
struct msg
{
int id;
byte type;
char text[100];
};
char* getText();
void setText(char* text);
private:
Dto::msg message;
...
dto.cpp
...
char* Dto::getText()
{
return Dto::message.text;
}
void Dto::setText(char* text)
{
Dto::message.text = text;
}
...
When I compile I get:
Dto.cpp:85:30: error: incompatible types in assignment of 'char*' to 'char [100]' Dto::message.text = text;
You can't assign to an array. To copy a C-string to a char array, you need strcpy:
strcpy(Dto::message.text, text);
Better yet, use strncpy to ensure you don't overflow the buffer:
strncpy(Dto::message.text, text, sizeof(Dto::message.text));
Dto::message.text[sizeof(Dto::message.text)-1] = 0;
Note that you need to manually add a null byte at the end if the source string is too big, since strncpy won't null terminate in that case.

c++ runtime dispatch of 2 sets of static constants

Motivation
A CLI app tries to make use of box drawing characters. But depending on the stdout device this may not be appropriate so there is a -t option to use pure ASCII text.
The concept is just an example, this applies anywhere where we want to select from two or more sets of static constants at runtime.
The question is what is reasonable c++ technique to facilitate this cleanly.
Desired usage Syntax
This is indicative only, but it the constant "invocation" should be terse
int main(int argc, char* argv[]) {
// using derived class style here, but anything would do
auto t = std::strcmp(argv[1], "-t") == 0 ? TxtTerminal() : BdTerminal();
// here we want the syntax to be short
std::cout << "text" << t.horiz << t.right_t << '\n';
}
Already tried
I have tried Base and Derived class style (as above) but there are issues. I can't put one set of constants in TxtTerminal and one in BdTerminal (which extends TxtTerminal).
Using static constants doesn't work, because C++ doesn't support "late static binding" , so it always uses the constants of whichever class you have the instance of.
Using member variables and proper instances of those classes (as hinted at above) doesn't work (nicely) either because the Derived class can't initialise the Base class members directly....
Nor via its constructor initialiser list ...
The derived class would have to pass the entire set to the base class constructor which then modifies the already (BaseClass)initialised values. Really awkward and long winded. I guess passing some struct config { .. }; could work
Similarly using a single class, putting both sets of constants in there in a map<key,config> and using a getter to retrieve the appropriate constant using a constructor initialised bool textmode member state variable.
Maybe with a templated solution taking some template parameter? Well no, because this is a runtime switch.
Similar to the template idea would be some kind of solution with using aliases for 2 separate constant namespaces..same problem..compile time..not runtime.
Using variable templates a bit like the new c++20 maths constants . Same problem, not runtime.
Of course all this const, ie strings of the control character for the "box drawing terminal" are just a bytes long each. Ideally these would just be compacted together as literal initialised const char* in the .text (linux) segment of the executable (std::string seems overkill). Wherever we compose these constants we would want easy concatenation to make the code readable and maintainable. That's not so easy with const char* string literals?
Many options, none seem great. Am I missing something obvious?
EDIT In response to questions below and also to the initial answer by #walnut here is some more fleshed out code using the "static non-instance" approach.
Some unsolved problems therein, see comments:
// NOTE this code compiles and runs, but doesn't quite do what we need
// see comments
#include <cstring>
#include <iostream>
struct TextMode {
static inline const auto cls = "TM cls";
static inline const auto right_t = "TM right_t";
static inline const auto left_t = "TM left_t";
};
struct BlockDrawMode {
static inline const auto cls = "BD cls";
static inline const auto right_t = "BD right_t";
static inline const auto left_t = "BD left_t";
};
struct Terminal {
Terminal(bool textmode = true) { mode = textmode ? &text_mode : &block_drawing_mode; }
// what is this type? some parent class of TextMode/BlockDrawMode?!
// then we get the initilisation loop again...
// ??????? // could be a reference initilised in cstr initilisation, but that's a detail
const TextMode* mode;
static inline const auto text_mode = TextMode{};
static inline const auto block_drawing_mode = TextMode{};
// obviously this needs to be .. ^ BlockDrawMode
// but then doesn't compile because there is no class hierarchy ...
};
int main(int argc, char* argv[]) {
Terminal t{strcmp(argv[1], "-t") == 0};
std::cout << t.mode->cls << '\n' << t.mode->right_t << '\n';
// output (-t makes no difference right now, due to the above issues)
// TM cls
// TM right_t
return 0;
}
EDIT2: I have added a self answer below which uses aggregate initialisation to avoid a lot of the unwanted inheritance complications. Feels a bit "dirty", but looks clean and works fine?
From the comments I gather that what you are looking for is:
If there aren't any other differences in behavior requiring a virtual interface or inheritance, then you can just define a pointer member which is chosen for the correct implementation at construction:
struct Terminal {
Terminal(/* parameters */) {
chooseConfig(/* some arguments */);
}
static constexpr char config1[]{/*...*/};
static constexpr char config2[]{/*...*/};
const char* config;
void chooseConfig(/*arguments*/) {
config = /*condition*/ ? config1 : config2;
};
// use `config` everywhere
};
int main(int argc, char* argv[]) {
Terminal terminal{/* arguments */};
//...
}
If all instances of this class are supposed to share the same configuration and passing the arguments to choose the configuration each time is too cumbersome, then you can also make config and chooseConfig static and instead of calling it in the constructor, call it once in main with Terminal::chooseConfig(/*arguments*/);.
A proposed "self answer":
Here is a version that avoids the hierarchy complications of the config structs. Basically aggregate initialization to the rescue...
This final version shows some proper terminal control strings and some tweaks using a ref to static inline struct. plus it uses designated initialisers. Note selective overrides from the Base Struct Config details would be possible if desired. All the "keys" are automatically checked at compile time, so prevent mistakes during maintenance.
struct Mode {
const char* const esc = "";
const char* const cls = "";
const char* const bd_on = "";
const char* const bd_off = "";
const char* const underline_on = "";
const char* const black = "";
const char* const red = "";
const char* const green = "";
const char* const yellow = "";
const char* const blue = "";
const char* const magenta = "";
const char* const cyan = "";
const char* const white = "";
const char* const reset = "";
const char horiz = '-';
const char vert = '|';
const char right_t = '|';
const char left_t = '|';
const char bottom_t = '|';
const char top_t = '|';
const char intersec = '|';
};
struct Terminal {
static inline const Mode text_mode;
// warning: this is a C99 extension until C++20 comes in
// but it nicely compile checks and self documents the code
// supported by gcc4.7, clang3.0 and msvc19.21
static inline const Mode box_draw_mode{
.esc = "\x1b",
.cls = "\x1b[2J",
.bd_on = "\x1b(0",
.bd_off = "\x1b(B",
.underline_on = "\x1b[4m",
.black = "\x1b[30m",
.red = "\x1b[31m",
.green = "\x1b[32m",
.yellow = "\x1b[33m",
.blue = "\x1b[34m",
.magenta = "\x1b[35m",
.cyan = "\x1b[36m",
.white = "\x1b[37m",
.reset = "\x1b[0m",
.horiz = '\x71',
.vert = '\x78',
.right_t = '\x75',
.left_t = '\x74',
.bottom_t = '\x76',
.top_t = '\x77',
.intersec = '\x6e',
};
const Mode& m;
Terminal(bool textmode = true) : m{textmode ? text_mode : box_draw_mode} {}
};
int main(int argc, char* argv[]) {
Terminal t1{true};
Terminal t2{false};
// usage
// std::cout << t1.m.cls << '\n' << t1.m.right_t << '\n';
// std::cout << t2.m.cls << '\n' << t2.m.right_t << '\n';
return 0;
}
Here is a godbolt (note that clang>3 and gcc>4.7 compile the designated initialisers just fine already). Also note that the godbolt shows that on -O3 the initializers get optimized away to the point were the char values just become inlined register loads. On O1 we can clearly see the strings laid out in .text segment and literally the only thing that happen during Terminal construction is the setting of a single pointer for Mode& m to point to one of the 2 structures: mov qword ptr [rdi], rcx. Good?

unable to Convert const char* table[] to NSArray in IOS for unity

Inside .mm I have some code as shown below.
extern "C"
{
void _AddNotification(const char* title,
const char* body,
const char* cancelLbl,
const char* firstLbl,
const char* secondLbl,
const char* tables[])
{
}
}
How can I get const char* table[] data into NSArray.Can anyone please help me.I couldn't find any solution for this in online.
NSArray only supports objects that are a type of NSObject, its subclasses. You will need to convert your values to NSString for instance using [NSString stringWithUTF8String:cString]. Or NSData like [NSData dataWithBytes:pointer length:sizeInBytes]. You can also play around with NSValue.
But in general it depends what is it you want to put inside your array.
EDIT: From comment "Can we get the count from const char* tables[]?"
You can not get that in your case by normal means.
Consider this array of strings:
static const char *table[] = {
"text a",
"text b",
"text c",
"text d"
};
Now if you have a direct access to the table you may get count by using sizeof doing:
int numberOfStringsInTable = sizeof(table)/sizeof(char*);
This will return 4. But as soon as we add a new variable such as in function
int tableLength(const char *stringTable[]) {
return sizeof(stringTable)/sizeof(char*);
}
And then calling tableLength(table); the result will be 1 instead of 4 as your program can not know the actual size of the table you are inserting.
But there are other means such like you can add an extra NULL at the end of array so you would declare it as:
static const char *table[] = {
"text a",
"text b",
"text c",
"text d",
NULL
};
And then to get a count of such table you would have:
int tableLength(const char *stringTable[]) {
for(int i=0;; i++) if(stringTable[i]==NULL) return i;
}
In your case you will probably need to figure out how the strings are layout in the table to see which procedure to use. But most usually you get a number somewhere in the function indicating the number of strings in the table.

C++11 Function That Only Accepts String Literals?

I want to write a C++11 function that will only accept string literals as a parameter:
void f(const char* s) { static_assert(s is a string literal); ... }
That is:
f("foo"); // OK
char c = ...;
f(&c); // ERROR: Doesn't compile
string s = ...;
f(s.c_str()); // ERROR: Doesn't compile
etc
Is there anyway to implement this? The signature of the function is open to changes, as is adding the use of macros or any other language feature.
If this is not possible what is the closest approximation? (Can user-defined literals help in anyway?)
If not is there a platform specific way in GCC 4.7 / Linux ?
I think the closest you are going to get is this
template<int N>
void f(const char (&str)[N]){
...
}
It will compile with literals and arrays but not pointers.
An alternative might be to make a GCC extension to check at compile time that your particular function is only called with a literal string.
You could use MELT to extend GCC. MELT is a high-level domain specific language to extend the GCC compiler, and is very well suited for the kind of check you want.
Basically, you would add a new pass inside GCC and code that pass in MELT which would find every gimple which is a call to your function and check that the argument is indeed a literal string. The ex06 example on melt-examples should inspire you. Then subscribe to gcc-melt#googlegroups.com and ask your MELT specific questions there.
Of course, this is not a foolproof approach: the function could be called indirectly thru pointers, and it could e.g. have a partial literal string, e.g. f("hello world I am here"+(i%4)) is conceptually a call with some literal string (e.g. in .rodata segment), but not in the generated code nor in the gimple.
I use this :
// these are used to force constant, literal strings in sqfish binding names
// which allows to store/copy just the pointer without having to manage
// allocations and memory copies
struct _literalstring
{
// these functions are just for easy usage... not needed
// the struct can be empty
bool equal(_literalstring const *other) { return !strcmp((const char *)this, (const char *)other); }
bool equal(const char *other) { return !strcmp((const char *)this, other); }
const char *str(void) { return (const char *)this; }
bool empty(void) { return *(const char *)this == 0; }
};
typedef _literalstring *LITSTR;
constexpr LITSTR operator "" _LIT(const char *s, size_t) {
return (LITSTR)s;
}
Then you just declare your function like this :
void myFunc(LITSTR str)
{
printf("%s\n", str->str());
printf("%s\n", (const char *)str);
const char *aVar = str->str();
const char *another = (const char *)str;
}
And you call it like this:
myFunc("some text"_LIT);
If you do something like this:
myFunc("some text");
myFunc(aTextVariable);
you get a compiler error.

C++: Define simple constant for use?

In C++ I wanted to define a constant that I can use in another function, A short answer on how to do this will be fine..
Lets say at the beginning of my code I want to define this constant:
//After #includes
bool OS = 1; //1 = linux
if (OS) {
const ??? = "clear";
} else {
const ??? = "cls";
}
I don't know what type to use to define the "clear" string... I'm so confused.
Later on I want to use it within a function:
int foo() {
system(::cls); //:: for global
return 0;
}
How would I define the string up top, and use the string down below? I heard char only had one character and things... I'm not sure how to use , since it says it's converting string into const char or something.
char* isn't quite a char. char* is basically a string (it's what strings were before C++ came along).
For illustration:
int array[N]; // An array of N ints.
char str[N]; // An array of N chars, which is also (loosely) called a string.
char[] degrades to char*, so you'll often see functions take a char*.
To convert std::string to const char*, you can simply call:
std::string s;
s.c_str()
In this case, it's common to use the preprocessor to define your OS. This way you can use the compiler to do the platform specific stuff:
#ifdef OS_LINUX
const char cls[] = "clear";
#elif OS_WIN
const char cls[] = "cls";
#endif
One thing you may want to consider is making it a function. This avoids nasty dependencies of global construction order.
string GetClearCommand() {
if (OS == "LINUX") {
return "clear";
} else if (OS == "WIN") {
return "cls";
}
FAIL("No OS specified?");
return "";
}
What it looks like you're trying to do is this:
#include <iostream>
using namespace std;
#ifdef LINUX
const char cls[] = "LINUX_CLEAR";
#elif WIN
const char cls[] = "WIN_CLEAR";
#else
const char cls[] = "OTHER_CLEAR";
#endif
void fake_system(const char* arg) {
std::cout << "fake_system: " << arg << std::endl;
}
int main(int argc, char** argv) {
fake_system(cls);
return 0;
}
// Then build the program passing your OS parameter.
$ g++ -DLINUX clear.cc -o clear
$ ./clear
fake_system: LINUX_CLEAR
Here's the problem, you're suffering from going out of scope with the variables. If I declare something within brackets, it only exists within the brackets.
if( foo ){
const char* blah = "blah";
}
Once we leave the if statement, the variable blah disappears. You'll need to instantiate it non-locally to whatever brackets you write. Hence:
void Bar(){
const char* blah = "blah";
if( foo ){
//blah exists within here
}
}
However, blah will not exist outside of Bar. Get it?
Yet another option is to create a class with a bunch of static methods. Create a new method for each command. Something like:
// in sys-commands.h
class SystemCommands {
public:
static char const* clear();
static char const* remove();
};
This gives you a few nice options for the implementation. The nicest one is to have a separate implementation file for each platform that you select during compile time.
// in sys-commands-win32.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "cls"; }
char const* SystemCommands::remove() { return "erase /f/q"; }
// in sys-commands-macosx.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "/usr/bin/clear"; }
char const* SystemCommands::remove() { return "/bin/rm -fr"; }
Which file gets compiled will determine which command set will be used. Your application code will look like:
#include <cstdlib>
#include "sys-commands.h"
int main() {
std::system(SystemCommands::clear());
return 0;
}
Edit: I forgot to mention that I prefer static functions to global constants for a bunch of reasons. If nothing else, you can make them non-constant without changing their types - in other words, if you ever have to select the command set based on runtime settings, the user code does not have to change or even be aware that such a change occurred.
You can use a common header file and link to different modules depending on the systen:
// systemconstants.hpp
#ifndef SYSTEM_CONSTANTS_HPP_INCLUDED
#define SYSTEM_CONSTANTS_HPP_INCLUDED
namespace constants {
extern const char cls[]; // declaration of cls with incomplete type
}
#endif
In case of Linux, just compile and link to this one:
// linux/systemconstants.cpp
#include "systemconstants.hpp"
namespace constants {
extern const char cls[] = "clear";
}
In case of Windows, just compile and link to this one:
// windows/systemconstants.cpp
#include "systemconstants.hpp"
namespace constants {
extern const char cls[] = "cls";
}
System-specific translation units could be placed in specific subdirectories (linux/, windows/, etc) of which one could be automatically selected during the build process. This extends to many other things, not just string constants.