1

The following C++ code outputs:

$ g++ -O3 c.cpp
$ ./a.out 
in func: 0x7fff5c1ecaf8
in main: 0x7fff5c1ecaf8
hello

C++ code:

#include <iostream>

using namespace std;

struct C {
    string s;
};

C f() {
    C c = {.s="hello"};
    cout << "in func: " << &c << endl;
    return c;
}

int main() {
    C obj = f();
    cout << "in main: " << &obj << endl;
    cout << obj.s << endl;

    return 0;
}

I have two questions regarding the code and output above:

  1. in the function f, c is created on the stack, and upon returning c, the caller in main got a copy of c, is it correct?
  2. if "Yes" is the answer to question 1, why the memory address of c in f is the same as the memory address of obj in main, as they are both 0x7fff5c1ecaf8 in the output?
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 4
    A very simple optimization by the compiler called [*copy elision*](http://en.cppreference.com/w/cpp/language/copy_elision). Why should the compiler make an actual copy if none is needed? – Some programmer dude May 28 '17 at 20:54
  • Thanks. So is it considered bad practice to write code like and and to rely on the compiler optimization? –  May 28 '17 at 20:56
  • 1
    No, this is the way you should usually do it IMO. – Some programmer dude May 28 '17 at 20:57
  • 2
    It's certainly bad practice to use C99 constructs like .`s="hello";` in C++ code, and not to include the correct header files for the Standard Library features you are trying to use. –  May 28 '17 at 20:58
  • @NeilButterworth I'm a C++ newbie, that's the way I initialize a struct ever since. So what is the recommended way? Thanks. –  May 28 '17 at 21:00
  • Alternatively, function call might have been inlined, i.e. there is no return and stack address is actually the same as in main. Check disassembly. – Ivan Aksamentov - Drop May 28 '17 at 21:00
  • 1
    Also note that compiler, OS and hardware do not execute the program that you write. They execute a program that is *equivalent* to yours in observed side effects (e.g. console printout). – Ivan Aksamentov - Drop May 28 '17 at 21:01
  • @Drop that kind of annoying, does it mean even my code is wrong, it works? –  May 28 '17 at 21:01
  • @Elgs I strongly doubt your C++ textbook told you to use that syntax. You are using a GCC extension. To diagnose faults like that use some extra compiler options like `-Wall -Wextra -pedantic`. –  May 28 '17 at 21:02
  • @ElgsQianChen it can be, sure. Check e.g. [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) – Ivan Aksamentov - Drop May 28 '17 at 21:03
  • Have linked to a question that explains what's going on. It'd be nice if C++ did support designated initializers for aggregates, and/or named parameters for constructors – M.M May 28 '17 at 21:14

0 Answers0