store non-nul terminated C string constant in C++ -


before says, "don't bad".

  1. i understand reasons having nul terminated string.
  2. i know 1 can state
    char mystr[] = { 'm', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g'};
    however, convenience of c-string representation great.

the rational i'm programming micro-controller , need store data programme's memory. of data in form of bytes, words, dwords , floats. i'd data include strings without nul contiguously.

i've tried templates take <size_t n, char* a> , <size_t n, char (&a)[n]> parameters in order traverse array , store contents static array, can't seem right. think standard may disallow understandable in general case, unfortunate in specific cases (specifically, one. ;) :( )

if remap string boost::mpl::vector_c<char, ...> template, better have other code store properly, dereferencing array within template used const template parameter appears disallowed too.

any ideas?

edit:

psudocode example (this kinda contrived real code larger, wouldn't read byte byte this, nor using literal iterate end of string. embedded in data somewhere.):

// stores bytes in array template<typename x, typename t, t ...numbers> struct x {   static progmem volatile const t data[]; }; template<typename x, typename t, t ...numbers> progmem volatile const t x<x, t, numbers...>::data[] = { numbers... };  void main() {   // not work, idea have byte 0 1,    // byte 1 2 byte 2 3 byte 3 's', byte 4 'o'...   // byte 22 'g', byte 23 4, byte 24 5, byte 25 6.   typedef x<int, char, 1,2,3,"some embedded string",4,5,6> xx;   for(i=0; i<20; ++i)     serial.print(pgm_read_byte_near(&xx::data[0] + 3)); } 

also note not using c++11, c++0x, , possibly extension.

third try

magic , trickery

if using c++11 (i know, in absence think code generation best bet), feels user-defined literal should able handle this. eg, with:

template <char... raw> inline constexpr std::array<char, sizeof...(raw)> operator "" _fixed() {     return std::array<char, sizeof...(raw)>{raw...}; } 

it nice if worked:

const std::array<char, 7> goodbye = goodbye_fixed; 

... sadly doesn't (the literal needs numeric, presumably parsing reasons). using "goodbye"_fixed doesn't work either, requires operator "" _fixed(const char *s, int length) overload , compile-time array has decayed pointer again.

eventually come down invoking this:

const auto goodbye = operator "" _fs <'g','o','o','d','b','y','e'>(); 

and it's no better ugly first version. other ideas?


second try

auto-generate ugliness

i think you're right can't intercept string literal mechanism. honestly, usual approach use build tool generate ugly code in separate file (cf. internationalization libraries, example).

eg, type

fixed_string hello = "hello"; 

or similar in dedicated file, , build system generates header

const std::array<char, 5> hello; 

and cpp ugly initialization above below.


first try

missed "looks string literal" requirement

i've tried templates ...

like this?

#include <array> const std::array<char, 5> hello = { 'h', 'e', 'l', 'l', 'o' };  #include <cstdio> int main() {     return std::printf("%.*s\n", hello.size(), &hello.front()); } 

if don't have c++11, boost.array work, or can roll own. note type wrapper around const char[5], should ok go in data segment (i've confirmed goes in .rodata local gcc).


Comments

Popular posts from this blog

c# - Operator '==' incompatible with operand types 'Guid' and 'Guid' using DynamicExpression.ParseLambda<T, bool> -