# Need funcion to return char[]?

## Recommended Posts

Vanz    204

I have some old code I'm trying to work with and I need a function to return a name, so for example:

[source]

int cApp::ReturnInt(int &Temp)

{

Temp=5;

return 6;

}

... later code...

int A,B;

A=ReturnInt(B);

[/source]

Returns A=5 and B=6

Now I need to do this with a char[] name, like this somehow:

[source]

char[20] cApp::ReturnInt(char[30] &Temp)

{

strcpy_s(Temp, "123");        //Add 123 into Temp
return "456";

}

... later code...

char[20] A,B;

A=ReturnInt(B);

[/source]

Which doesn't work of course, but I hope you get the gist of what I'm trying to do... I don't need it to return the name both ways (using return and &) just any way...

It's too hard for me to update all the code to string but if you have the time I'd also like to see how it's done with string...

Hope this makes sense...

Thanks,

Vanz

##### Share on other sites

As SiCrane is hinting at, with C++ always prefer std::string unless you have a real reason not to.

##### Share on other sites
Vanz    204

Thanks SiCrane, I think I can work with that...

##### Share on other sites
Vanz    204

As SiCrane is hinting at, with C++ always prefer std::string unless you have a real reason not to.

ya I do, like I said above I'm working with some really old code and it'll take too long to convert it all...

##### Share on other sites
ultramailman    1720
You can't return arrays. Instead, you can return a pointer to char. You will have to pass in the return value too.
char * example(char Temp[], char * buf)
{
//do work to temp, store result to buf
return buf;
}


##### Share on other sites

As SiCrane is hinting at, with C++ always prefer std::string unless you have a real reason not to.

ya I do, like I said above I'm working with some really old code and it'll take too long to convert it all...

It'll take too long on the front end, but over the lifetime of the project, you'll probably waste more time fighting the chars.
If you have deadlines though, then there may not be enough time to meet the deadlines and refactor the project. Still, if you could schedule a time (three days or whatever you estimate it'll take) in the near future to refactor that aspect of the project, I think you'll feel alot better about it - and the code will certainly benefit from it.

But that's just my opinion!

Even if you can't use std::strings everywhere, you could still use them as a container-type for char arrays.

std::string cApp::ReturnString(char[30] &Temp)
{
std::string copy(temp, 30);
//...
return copy;
}

... later code...
std::string B;
std::string A = DoSomething(B[0], B.size());

(Assuming DoSomething() already exists as part of the old code-base and can't be changed. Otherwise, it'd be much better off just taking a std::string)

But everything new you write would be much better off as std::string.
If you absolutely have-to-have-to-have-to, you could do something like this:

struct CharArrayStruct30
{
char data[30]; //Horrible. *shudders*
};

But even this would be a step up:

struct RawStringStruct
{
char *data;
size_t size;
};

But std::strings constructors and functions are compatible with C-style raw strings, so you can migrate your codebase away slowly if you like.

##### Share on other sites
Vanz    204

cool... thanks....

##### Share on other sites
Serapth    6671

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

##### Share on other sites
Waterlimon    4398
You could make a template class to do something like

Array<char,30> chars;
chars.array[3]='a';

Which should work as a return value/patameter, and you dont need a new struct for different array sizes.

Unless you can just use string of course.

##### Share on other sites
SiCrane    11839
If you have a C++11 compiler, there's already a class that does that: std::array. If not, you can also use boost::array, which it is based on.

##### Share on other sites
King Mir    2490

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

##### Share on other sites
ultramailman    1720

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

What do you suppose an array is then, if not a continuous block of memory?

##### Share on other sites
King Mir    2490

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

What do you suppose an array is then, if not a continuous block of memory?

It's a type.

An array represents a monotonous aggregate of types in continious memory, but it is a type in its own right, and destinct from several other ways the same concept could be expressed.

##### Share on other sites
ultramailman    1720

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

What do you suppose an array is then, if not a continuous block of memory?

It's a type.

An array represents a monotonous aggregate of types in continious memory, but it is a type in its own right, and destinct from several other ways the same concept could be expressed.

Oh thanks. Upon closer inspection, I realized your first post already said an array is a type. I guess I was paying more attention to the "...distinct from the concept of..." part.

I would say an array is a type, an array variable is a variable, and is also a contiguous block of memory.

##### Share on other sites
Trienco    2555

One of the few situations where a programmer will see an actual difference is references.

void func( int(&a)[10] ) { ... }

This will take an actual array, it must contain ints and it must be size 10. The last part is what often makes it useless in practice compared to "(int* a, size_t num)".

##### Share on other sites
SiCrane    11839
In technical jargon C++ arrays are not first class types. In other words there are many instances where arrays are treated differently than other types. One of the differences is that while you can declare a function to take an array as a function parameter, the compiler will automatically transform all array function parameters to pointers. This means it's impossible to pass a regular array by value. It's also illegal to return an array from a function. Unlike most other types, a variable with array type is not a legal lvalue. Pre-C++11 there was no way to initialize an array in a member initialization list. cv-qualifiers in an array declaration can't be applied to the array type, only the members of the array and so on. Arrays are types, but special cases.

##### Share on other sites

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

Exactly what distinction exists about arrays that does not amount to syntactic sugar?  I can use array subscript notation to navigate through newed/malloced memory, and I can use pointer arith to navigate static/stack based arrays.  As far as I'm aware, all of the inconsistencies of array notation in C\C++ are a result of the fact that, under the covers, arrays are just pointers to a block of data, however that data is allocated, and array subscript notation is just another form of dereferencing that pointer.

##### Share on other sites
SiCrane    11839

under the covers, arrays are just pointers to a block of data

There's a subtle difference between a variable being a block of memory and a variable being a pointer to a block of memory, which is best illustrated by looking at the assembly generated when you access the two. Consider this code:
void foo(int);
int main(int, char **) {
int a[5];
foo(a[1]);
}

The relevant bits of the assembly of the function call look like this under MSVC x64:
	mov	ecx, DWORD PTR a$[rsp+4] call ?foo@@YAXH@Z ; foo  Change the array to a pointer and the generated assembly changes:  mov rax, QWORD PTR a$[rsp]
mov	ecx, DWORD PTR [rax+4]
call	?foo@@YAXH@Z				; foo

With the variable declared as an array, you can get the address of the array member by adding to the stack pointer. With the variable declared as a pointer, you need to load the value of the pointer and then get the address of the member. Under the hood, arrays and pointers behave somewhat differently. Of course C does your best to confuse you about the difference between pointers and arrays by doing things like implicit decay and argument type transformation, which C++ unfortunately inherits.

##### Share on other sites

Thanks for the example SiCrane.  That's definitely more than syntactic sugar.  I'm curious to know though if that is per the C spec, or a compiler optimization.

##### Share on other sites
SiCrane    11839
You always have an extra operation when using a pointer to an object rather than the object itself, whether that be an int or a contiguous row of ints. It's pretty much built in to the idea of pointer versus object. Same deal when you have an array member as a part of a class. The compiler doesn't stick a pointer in the class layout and then the members of the array somewhere else, the array is embedded in the class. So if you use a pointer in place of an array, instead of needing an additional dereference on the stack pointer, you need an additional dereference based on the this pointer. Since you don't need an additional dereference in the code using a pointer like an array in C, it's very easy to forget the fact that the dereference is there.

##### Share on other sites
King Mir    2490

I mentioned this in another thread, and this is a common tripping point, but an array isn't really a variable, its just a trick to look like one.  At the end of the day, an array is just syntactic sugar over a continuous block of memory.

That's incorrect. An array is a type that's distinct from the concept of a continuous block of memory. In particular, dynamic arrays returned by new or malloc (and other functions) represent continuous blocks of memory, but are not of array type. Arrays are just a somewhat inconsistant feature of C/C++. It's not sugar.

But it's true that arrays behave differently from other variable types.

Exactly what distinction exists about arrays that does not amount to syntactic sugar?  I can use array subscript notation to navigate through newed/malloced memory, and I can use pointer arith to navigate static/stack based arrays.  As far as I'm aware, all of the inconsistencies of array notation in C\C++ are a result of the fact that, under the covers, arrays are just pointers to a block of data, however that data is allocated, and array subscript notation is just another form of dereferencing that pointer.

As SiCrane illistrated, arrays are not just poiners to dynamic memory. They are instead a block of memory inline with the other variables in the scope they are declared, be that the stack, inside a class, or as global. This is most apparent in the disharmony between 2D arrays, and what would be the dynamic equivilent, an array of pointers to dynamic arrays.

This:

int array1[10][10] = {{}};

array1[4][6]=1;

Creates a continious block of memmory typically of 400 bytes. The indexing is equivelent to somthing like (int*)(int(array1) + 10 * 4 + 6). Also, as pointed out, the base pointer itself does not live in memory.

This:

int **array2 = new int *[10];
for(int i=0;i<10;++i)
array2 = new int[10];
array1[4][6]=1;


Creates an array of pointers to array. It uses a total of 440 bytes, on 32 bit processors, typically. The index calculation is trivial: *(array2+4)+6, but it does two extra memory loads.

(Note: I have not tested the code, and it may contain typos or errors)