When to Return a Pointer, Scalar and Reference in C++

Passing by reference in C

Because you're passing the value of the pointer to the method and then dereferencing it to get the integer that is pointed to.

Why can I use scalar type as the return type of operator-?

While the standard doesn't directly place restrictions on the return type of operator->, it does describe what happens when the overloaded -> operator is used:

12.6.5 Class member access [over.ref]

A class member access operator function is a function named operator-> that is a non-static member function taking no parameters. For an expression of the form

    postfix-expression -> template(opt) id-expression
the operator function is selected by overload resolution (12.4.1.2), and the expression is interpreted as

     ( postfix-expression . operator -> () ) -> template(opt) id-expression.

So when using your class, you can call the overloaded operator like a normal function by writing a.operator->(). But if you attempt to use the operator with a->name, this is interpreted as (a.operator->())->name which won't compile because it attempts to use -> on an int.

Trying to understand how a pointer return type works

The easiest way to see the difference is to generate the dissasembly of a simple hello-world-ish example:

char* test() {
return "Test";
}

int main(int argc, char* argv[]) {
return 0;
}

This is the diassembly with gcc in FreeBSD with optimization turned off

    .file   "hellow.c"
.section .rodata
.LC0:
.string "test"
.text
.p2align 4,,15
.globl test
.type test, @function
test:
pushl %ebp
movl %esp, %ebp
movl $.LC0, %eax
popl %ebp
ret
.size test, .-test
.p2align 4,,15
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
call test
movl $0, %eax
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]"

As you can see, the string literal itself was stored in the .LC0 section, not in the code itself. The test function just return a pointer to the beginning of .LC0 (movl $.LC0, %eax) as this is the first string literal. The location is similar (but not the same) depending the executable format you are compiling to. Read A.out (text segment), or PE.

Is it safe to return a struct in C or C++?

It's perfectly safe, and it's not wrong to do so. Also: it does not vary by compiler.

Usually, when (like your example) your struct is not too big I would argue that this approach is even better than returning a malloc'ed structure (malloc is an expensive operation).

Getting a dangling pointer by returning a pointer from a local C-style array

No, it's not UB.

This:

const char* f()
{
const char* arr[]={"test"};
return arr[0];
}

Can be rewritten to the equivalent:

const char* f()
{
const char* arr0 = "test";
return arr0;
}

So we're just returning a local pointer, to a string literal. String literals have static storage duration, nothing dangles. The function really is the same as:

const char* f()
{
return "test";
}

If you did something like this:

const char* f() {
const char arr[] = "test"; // local array of char, not array of char const*
return arr;
}

Now that is UB - we're returning a dangling pointer.



Related Topics



Leave a reply



Submit