Search code examples
c++uint8t

In C++, why would you use `uint8_t` to declare a string?


As a mobile developer working with React Native, I need to work with a C++ code that creates and encrypts files. I don't have much experience with C++ (the last time I wrote some was over 15 years ago at university).

Please correct me if I'm wrong.

This bugs me so much. Here is the type definition of the file:

typedef struct File 
{
    uint8_t FileName[64];
    uint8_t userName[64];
}File;

Why would you use the type uint8_t to store string instead of std::string?

Later on, it becomes even more confusing. We need to parse all the characters one by one and write them to a temporary file.

#define FILE_NAME_LEN   64


CustomFile CFile::getCustomFileFromFile(tFile f_File)
{
    CustomFile returnValue;
    for(int i = 0;i<FILE_NAME_LEN;i++){
        returnValue.FileName[i] = f_File.FileName[i]; 
    }
    for(int i = 0;i<FILE_NAME_LEN;i++){
        returnValue.user_name[i] = f_File.user_name[i];
    }
    return returnValue;
}



bool WriteEncryptFile(QString fpath,tFile *p_tFile)
{
    // Convert the tFile object to a CustomFile object
    CustomFile customFile = CFile::getCustomFileFromFile(*p_tFile);
}

Solution

  • Why would you use the type uint8_t to store string instead of std::string

    Because whoever decided to do so is a C developer with little expertise in idiomatic C++. This can also be seen in habits like:

    That being said, there are practical reasons too. std::string performs dynamic allocations, and this may not be desirable, especially in an embedded environment. Still, it would probably make more sense to use char FileName[64]; instead.

    The use of uint8_t likely comes from a desire to make the code "more portable", since char is not guaranteed to be 8 bits large (it can be wider). It probably is on any machine you will ever compile your code on, but still, some people are annoyed by this technicality and use uint8_t. See also When is uint8_t ≠ unsigned char?

    It may also be motivated by the varying signedness of char, though signed char or unsigned char solve that. See also Is char signed or unsigned by default?

    If you have the freedom to modify the original code, and dynamic allocations are acceptable, you can simply write:

    struct File {
        std::string FileName;
        std::string userName;
    };
    

    If you need all string data to be in the struct, you can use std::array<char, 64> instead. This still simplifies the subsequent code because you can write:

    // std::array has an assignment operator
    returnValue.FileName = f_File.FileName;