简体   繁体   中英

How to pass char array as const char* arg?

How to pass char array[] to function accepting const char* arg type and what is the most proper way of doing that?

Please ignore the fact that I'm using static 100 buffer in this example:

char buff[100];
sprintf_s(buff, sizeof(buff), "%s", unrelated);

Then I need to pass the buff to the function accepting const char*

MyFunction(const char* path);

I tried passing it directly: MyFunction(buff) and it works, but could someone exaplain why? and if there is better way to achieve the same result?

I tried passing it directly: MyFunction(buff) and it works, but could someone exaplain why? and if there is better way to achieve the same result?

A "better way" is open to lots of interpretation. Some here at SO would insist that std::string is the C++ way and therefore always better than a char[] but the truth is that it depends on what you're doing. If you are trying to avoid dynamic memory allocations then certainly what you have is acceptable and maybe even the "best way". However, if you are dynamically allocating memory for your buffer array ie const char* buff = new char[BUFF_SIZE]; then I would argue that the "better way" is to use std::string for many reasons not the least of which is that it manages its own memory. In your case you could use it like this.

std::string buff;
MyFunction(buff.c_str());

Why does passing a char[] to a const char* work?

It works because array names decay into pointers to the first element when used in expressions. In your example, char buff[100] decays to a pointer char* when it's passed into MyFunction . You are also allowed to pass non-const arguments as const because MyFunction is making the guarantee not to mutate the data. This implicit conversion to const is fine and allowed.

A properly terminated const char* is "special" and will have a \\0 sentinel value at the end so you do not need to specify the size of the buffer being passed into the function as you would with all other types of arrays. The function being called will check for this null terminator and stop at the appropriate length without going out-of-bounds. I am making an assumption that your MyFunction(const char* path); checks for a properly null terminated C-string in this way, and if it doesn't then it must be making some potentially dangerous assumptions about path .

The function signature can be rewriten as:

int MyFunction(char const * buff);

Reading the type, from right to left, the function is requiring a pointer to a constant buffer of char (read-only). The function is promising it will not change the content of buff .

You can pass a mutable buffer (non-const) because the function will not modify the buffer. This is allowed.

You cannot pass a pointer to a constant (read only) buffer to a function that will modify the buffer.

int MutateBuffer(char * buffer);

The above is a signature of a function that may write to the buffer. So, passing a read-only buffer to this function is not advised and the compiler will warn about it at least.

The array "decays" into a pointer to the same memory. So long as the data in the array has a sentinel (NUL-byte) at the end, the callee only needs the pointer and can use the buffer up to the sentinel.

Alternatively, if it's not a C-string (ie. there is no sentinel; the sentinel is the convention that makes an array a C-string), then you'd also need to pass the length of the buffer (generally sizeof(buff) ) so the callee knows how long the buffer is — to avoid overrunning it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM