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);
}
Why would you use the type
uint8_t
to store string instead ofstd::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:
uint8_t
instead of std::uint8_t
despite potential compatibility issuesstd::array
typedef struct File
even though typedef
is unnecessary here
constexpr
constants (assuming that isn't your code)
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;