A use case for fromStringz

Andrej Mitrovic andrej.mitrovich at gmail.com
Fri Apr 15 21:55:50 PDT 2011


Microsoft has some of the most ridiculous functions. This one
(GetEnvironmentStrings) returns a pointer to a block of
null-terminated strings, with no information on the count of strings
returned. Each string ends with a null-terminator, standard stuff. But
only when you find two null terminators in succession you'll know that
you've reached the end of the entire block of strings.

So from some example code I've seen, people usually create a count
variable and increment it for every null terminator in the block until
they find a double null terminator. And then they have to loop all
over again when constructing a list of strings.

Talk about inefficient designs.. There's also a wchar* edition of this
function, I don't want to even touch it. Here's what the example code
looks like:

    char *l_EnvStr;
    l_EnvStr = GetEnvironmentStrings();

    LPTSTR l_str = l_EnvStr;

    int count = 0;
    while (true)
    {
        if (*l_str == 0)
            break;

        while (*l_str != 0)
            l_str++;

        l_str++;
        count++;
    }

    for (int i = 0; i < count; i++)
    {
        printf("%s\n", l_EnvStr);
        while(*l_EnvStr != '\0')
            l_EnvStr++;

        l_EnvStr++;
    }

    FreeEnvironmentStrings(l_EnvStr);

I wonder.. in all these years.. have they ever thought about using a
convention in C where the length is embedded as a 32/64bit value at
the pointed location of a pointer, followed by the array contents?

I mean something like the following (I'm pseudocoding here, this is
not valid C code, and it's 7 AM.):

// allocate memory for the length field + character count
char* mystring = malloc(sizeof(size_t) + sizeof(char)*length);
*(cast(size_t*)mystring) = length;  // embed the length

// call a function expecting a char*
printString(mystring);

// void printString(char* string)
{
    size_t length = *(cast(size_t*)string);
    (cast(size_t*)string)++;  // skip count to reach first char

    // now print all chars one by one
    for (size_t i; i < length; i++)
    {
        printChar(*string++);
    }
}

Well, they can always use an extra parameter in a function that has
the length, but it seems many people are too lazy to even do that. I
guess C programmers just *love* their nulls. :p


More information about the Digitalmars-d-learn mailing list