How readily do unterminated char arrays in C++?

狂风中的少年 提交于 2020-01-24 10:14:08

问题


Sorry if this is solvable via Google -- I couldn't find anything.

char foo[4] = "abcd";

is invalid in C++ (due to the need for '\0' terminator) but IIRC valid in C -- is that correct?

I have a set of structs with a large number of "fixed length" character fields that are to be blank-padded and not '\0' terminated. I would like to be able to do the usual sort of struct initialization -- you know

mystruct bar = {17, "abcd", 0x18, "widget  ", ...

But I can't do that in C++. One solution I guess would be to put all of the initialized structs like this into their own C (not ++) source module. The ugly, laborious solution that I am trying to avoid is

mystruct bar = {17, {'a', 'b', 'c', 'd'}, 0x18, {'w', 'i', 'd', 'g', 'e', 't', ' ', ' '}, ...

Is there a good C++ solution? A clever macro that will effectively let "abcd" be char[4] with no '\0' terminator?

Thanks, Charles


回答1:


You could use a macro that will do the job:

#define MACRO_GET_1(str, i) \
    (sizeof(str) > (i) ? str[(i)] : 0)

#define MACRO_GET_4(str, i) \
    MACRO_GET_1(str, i+0),  \
    MACRO_GET_1(str, i+1),  \
    MACRO_GET_1(str, i+2),  \
    MACRO_GET_1(str, i+3)

#define MACRO_GET_STR(str) MACRO_GET_4(str, 0)

struct mystruct {
    char foo[4];
};

int main() {
    mystruct obj{ MACRO_GET_STR("abcd") };
    const char* str = "abcd";
    std::cout << memcmp(obj.foo, str, 4); // 0

    return 0;
}

Example

This code is based on this solution and it is also easily extendable.

Anyway there was a proposal some time ago that probably never made it to the standard. There are patches around that allow string literals to be converted into variadic char packs.




回答2:


Give the struct a constructor that accepts char arrays of size 1 greater than what you need, and ignore the terminating character when copying them over.

bar::bar(int, char const(&)[5], int, char const(&)[9], ...)

Or, you can just make the parameters char const* and trust the user to pass correctly sized arrays, in accordance with your documentation. If you don't want to, or can't, add anything to the struct, then just create a function with those same arguments which returns one (RVO should eliminate extra copying).




回答3:


I think it will work as a uint8 array (or whatever your compiler supports). Just don't ever think it's a string, because it is not. It's MUCH safer the allocate an extra char and initialise to zero (usually automatic). It is better still to use STL components, unless there is a very good reason to do something else.

C++ is not C. In C++ the compiler tries to keep you safe. In C it is entirely your own lookout.



来源:https://stackoverflow.com/questions/26613420/how-readily-do-unterminated-char-arrays-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!