cstringpascal

Declaring Pascal-style strings in C


In C, is there a good way to define length first, Pascal-style strings as constants, so they can be placed in ROM? (I'm working with a small embedded system with a non-GCC ANSI C compiler).

A C-string is 0 terminated, eg. {'f','o','o',0}.

A Pascal-string has the length in the first byte, eg. {3,'f','o','o'}.

I can declare a C-string to be placed in ROM with:

const char *s = "foo";

For a Pascal-string, I could manually specify the length:

const char s[] = {3, 'f', 'o', 'o'};

But, this is awkward. Is there a better way? Perhaps in the preprocessor?


Solution

  • I think the following is a good solution, but don't forget to enable packed structs:

    #include <stdio.h>
    
    #define DEFINE_PSTRING(var,str) const struct {unsigned char len; char content[sizeof(str)];} (var) = {sizeof(str)-1, (str)}
    
    DEFINE_PSTRING(x, "foo");
    /*  Expands to following:
        const struct {unsigned char len; char content[sizeof("foo")];} x = {sizeof("foo")-1, "foo"};
    */
    
    int main(void)
    {
        printf("%d %s\n", x.len, x.content);
        return 0;
    }
    

    One catch is, it adds an extra NUL byte after your string, but it can be desirable because then you can use it as a normal c string too. You also need to cast it to whatever type your external library is expecting.