-2

I have a third-party library, which has a function delared as follows:

void foo(const void* input, char output[1024]);

If I write something like this:

char* input = "Hello";
char  output[1024];
foo(input, output); // OK

But I don't want to declare such a big array on stack (that would be very dangerous in OS kernel environment). So I have to do something like this:

char* input      = "Hello";
char* output_buf = new char[1024];
foo(input, output_buf); // Compiler Error C2664

I cannot change the implementation of foo. How should I do?

=================

The problem has been resolved. My real code is like this:

char* input      = "Hello";
void* output_buf = new char[1024];
foo(input, output_buf); // Compiler Error C2664

conversion from void* to char* is not implicitly accepted by the standard. So the following code works:

char* input      = "Hello";
void* output_buf = new char[1024];
foo(input, (char*)output_buf); // OK
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • what about input's declaration? – AgA Dec 16 '12 at 17:10
  • input has nothing to do with this problem. So I omitted it. – xmllmx Dec 16 '12 at 17:11
  • Using `new` can be even more dangerous "in OS kernel environment" (it can throw.) Use `malloc`, and cast. – vladr Dec 16 '12 at 17:13
  • 1
    @xmllmx: I think you're wrong about that. You're assuming input has nothing to do with your problem because you do not understand how `output` is actually passed to `foo`. However, `output` is almost certainly the problem. – Ed S. Dec 16 '12 at 17:15
  • @xmllmx To the contrary, declaring a large object had better be on the stack, unless you are sure that your stack size limit does not allow that. http://stackoverflow.com/questions/333443/c-object-instantiation – PoP Dec 16 '12 at 17:21
  • 1
    Incidentally, @xmllmx, what is the **full** error message (parameter number, type), and are `char` the actual types the real code uses? – vladr Dec 16 '12 at 17:23
  • @PoP: if an object is large the rule of thumb is that it goes on the heap to avoid risking a stack overflow even in reasonable scenarios; of course an object is considered "large" or "small" in comparison to the stack size - e.g. on a "normal" user-mode 1 MB stack 1 KB is usually "small" (unless there's recursion), but in other situations it may not be so. – Matteo Italia Dec 16 '12 at 17:27
  • That's totally due to my carelessness. I have edited the original post. – xmllmx Dec 16 '12 at 17:27
  • 1
    @xmllmx: also, remember that string literals are of type `const char *`, not just `char *` (there's a deprecated implicit conversion, but it will usually just give you needless headaches). – Matteo Italia Dec 16 '12 at 17:29

2 Answers2

3

That's strange, since in C++ any function argument of array type is actually considered of pointer type, i.e. the "real" function signature seen by the compiler is

void foo(const void* input, char* output);

After determining the type of each parameter, any parameter of type “array of T” [...] is adjusted to be “pointer to T” (C++11, [dcl.fct], ¶5)

Most importantly, your code does work, as you can see here; are you sure that your "narrowed down" example actually reflects the problem you are seeing? Probably the problem lies in the type of another parameter.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 1
    +1 I concur with this answer, except to note the subtle nuance of the standard, which in-reality identifies the specific *leading* array subscript as the degenerate pointer. This becomes important with multi-subscript arrays. I.e. `foo(char ar[10][20]` degenerates to `foo(char (*ar)[20])` (or `foo(char ar[][20])` if you prefer). This allows you to pass a `char[2][20]` but *not* a `char[10][10]` to said function. – WhozCraig Dec 16 '12 at 18:33
2

The problem is not with output. In reality your function does not take an array as you cannot pass arrays to functions. It receives a pointer to char. This would work as well:

void foo(char f[1024])
{
    // blah
}

int main() {
    char c1[1];
    foo(c1);  // works!

    char *c2 = new char[27];
    foo(c2);  // works!

    delete [] c2; 
}

That code will compile, and it does so because the function receives a pointer, that is all. So, the problem is with your first argument, input. It's type must be wrong. Look at your error message more closely and/or show us the declaration of input.

Ed S.
  • 122,712
  • 22
  • 185
  • 265