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 namedoperator->
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
How to Get Duration, as Int Milli's and Float Seconds from <Chrono>
Techniques for Obscuring Sensitive Strings in C++
Any C/C++ Refactoring Tool Based on Libclang? (Even Simplest "Toy Example" )
Explicitly Exporting Shared Library Functions in Linux
Are the Character Digits ['0'..'9'] Required to Have Contiguous Numeric Values
Easiest Way to Flip a Boolean Value
C++ Abstract Class: Constructor Yes or No
Using Pre-Compiled Headers with Cmake
C/C++ Counting the Number of Decimals
Std::Variant' VS. Inheritance VS. Other Ways (Performance)
How to Profile Multi-Threaded C++ Application on Linux
How Can Duff's Device Code Be Compiled
Why Cast to a Pointer Then Dereference
How to Do Performance Test Using the Boost Library for a Custom Library
What Are Consequences of Forcing Qobject as a Parent of Qwidget
Why Do I Need to Repeat Template Arguments of My Base Class in Member Initalizer List