Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8486571
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T20:58:55+00:00 2026-06-10T20:58:55+00:00

I’m trying to educate myself on move constructors and move assignment so I can

  • 0

I’m trying to educate myself on move constructors and move assignment so I can get my students started on this feature of C++11. I’ve seen (and explained elsewhere on this site) that compilers will optimize away the move (or ordinary) construction in most cases so you can’t see it at work. With gcc 4.7.0, the -fno-elide-constructors option will turn that off and you can see move construction happening. But that same flag is supposed(?) to be clang option, and when I specify it as “Other C++ flags” in Xcode 4.4.1 with clang, c++11, and stdc++, apparently a returned value doesn’t get copied or moved out at all!

Here is the complete test code and the output annotated with where the problem happens:

#include <iostream>
using namespace std;

class Array_Exception {
public:
Array_Exception (int v, const char * msg) :
    value (v), msg_ptr(msg) {}

int value;
const char * msg_ptr;
};

class Array {
public:
Array() : size(0), ptr(nullptr), serial_number(++counter) {
    cout << "Array " << serial_number << " default constructed";
    }

Array(int size_) : size(size_), serial_number(++counter) {
    if(size <= 0)
        throw Array_Exception(size, "size must be greater than 0");
    ptr = new int[size];
    cout << "Array " << serial_number << " constructed" << endl;
    }

Array(const Array& source) : size(source.size), ptr(new int[size]), serial_number(++counter) {
    for (int i = 0; i < size; i++)
        ptr[i] = source.ptr[i];
    cout << "Array " << serial_number << " constructed from " << source.serial_number << endl;
    }

// move constructor - take the guts from the source and leave it in a safely destructable state
Array(Array&& source) : size(source.size), ptr(source.ptr), serial_number(++counter) {
    source.size = 0;
    source.ptr = nullptr;
    cout << "Array " << serial_number << " move constructed from " << source.serial_number << endl;
    }

// copy the data from rhs into lhs object using copy-swap
Array& operator= (const Array& source) {
    Array temp(source);
    swap(temp);
    cout << "Array " << serial_number << " assigned from " << source.serial_number << endl;
    return *this;
    }

// move assignment just swaps source with this.
Array& operator= (Array&& source) {
    swap(source);
    cout << "Array " << serial_number << " move assigned from " << source.serial_number << endl; 
    return *this;
    }

// swap the member variable values of this object with the other (serial_numbers are NOT swapped)
void swap(Array& other) {
    int t_size = size;  // could use std::swap
    size = other.size;
    other.size = t_size;
    int * t_ptr = ptr;
    ptr = other.ptr;
    other.ptr = t_ptr;
    }       

~Array() {
    delete[] ptr; 
    cout << "Array " << serial_number << " destroyed" << endl;
    }   

int get_size() const {return size;}

// overloaded plus operator returns an Array containing the sum of the two
Array operator+ (const Array& rhs) { // "this" object is lhs
    // must have the same size
    if(size != rhs.get_size())
        throw Array_Exception(size, "LHS and RHS must have the same size for +");
    Array result(size);
    for(int i = 0; i < size; i++)
        result[i] = ptr[i]+rhs[i];
    return result;
    }

const int& operator[] (int index) const {
    if ( index < 0 || index > size - 1) {
        throw Array_Exception(index, "Index out of range");
        }
    return ptr[index];
    }

int& operator[] (int index) {
    if ( index < 0 || index > size - 1) {
        throw Array_Exception(index, "Index out of range");
        }
    return ptr[index];
    }

private:
int size;
int* ptr;
int serial_number;
static int counter; 
};

int Array::counter = 0;

void print_all(const char * msg, const Array& a);
Array reverse_contents(Array a); // call and return by value

int main()
{   

Array a(5), b(5), c(5);
for (int i = 0; i < 5; i++)
    a[i] = i;   // 0, 1, 2, 3, 4

try {            
    cout << "\ncall by value and assign from returned value:" << endl;
    print_all("a has", a);
    b = reverse_contents(a);
    print_all("b has reversed", b);

    cout << "\nassign from rvalue expression" << endl;
    c = a + b;
    print_all("c has sum", c);

    cout << "\nconstruct from rvalue expression" << endl;
    Array e(a + c);
    print_all("e has copy of a + c", e);

    cout << "\nconstruct from function return value" << endl;
    Array d(reverse_contents(a));
    print_all("d has returned reverse of a", d);

   }

catch (Array_Exception& x) {
    cout << x.msg_ptr << ' ' << x.value << endl;
    }

cout << "\nDone!" << endl;
}

void print_all(const char * msg, const Array& a) {
cout << msg << ": ";
for(int i= 0; i < a.get_size(); i++)
    cout << a[i] << ' ';
cout << endl;
}

Array reverse_contents(Array a) {
int n = a.get_size();
Array result(n);

for(int i = 0; i < n; i++) {
    result[i] = a[n-i-1];
    }
return result; 
}

Running this with clang and -fno-elide constructors doesn’t get very far: the local variable in the called function gets destroyed during the return and we end up doing a move assignment from a bogus object:

Array 1 constructed
Array 2 constructed
Array 3 constructed

call by value and assign from returned value:
a has: 0 1 2 3 4 
Array 4 constructed from 1
Array 5 constructed
Array 5 destroyed  << local Array has been destructed
Array 2 move assigned from 0  << Array with serial_number == 0 is bogus object
Array 0 destroyed << bogus object destroyed here
Array 4 destroyed
b has reversed: << nothing in the returned result

The program halts in the next test because b doesn’t have anything in it.

The same code running under gcc 4.7.0 seems to make sense and shows move construction at work:
g++ -std=c++11 *.cpp -fno-elide-constructors

Array 1 constructed
Array 2 constructed
Array 3 constructed

call by value and assign from returned value:
a has: 0 1 2 3 4 
Array 4 constructed from 1
Array 5 constructed
Array 6 move constructed from 5
Array 5 destroyed
Array 2 move assigned from 6
Array 6 destroyed
Array 4 destroyed
b has reversed: 4 3 2 1 0 

assign from rvalue expression
Array 7 constructed
Array 8 move constructed from 7
Array 7 destroyed
Array 3 move assigned from 8
Array 8 destroyed
c has sum: 4 4 4 4 4 

construct from rvalue expression
Array 9 constructed
Array 10 move constructed from 9
Array 9 destroyed
Array 11 move constructed from 10
Array 10 destroyed
e has copy of a + c: 4 5 6 7 8 

construct from function return value
Array 12 constructed from 1
Array 13 constructed
Array 14 move constructed from 13
Array 13 destroyed
Array 15 move constructed from 14
Array 14 destroyed
Array 12 destroyed
d has returned reverse of a: 4 3 2 1 0 
Array 15 destroyed
Array 11 destroyed

Done!
Array 3 destroyed
Array 2 destroyed
Array 1 destroyed

So turning off elision gives a sensible result in gcc 4.7, but produces broken code in clang. Is this a bug in clang, or is that compiler option actually not supported in clang?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T20:58:57+00:00Added an answer on June 10, 2026 at 8:58 pm

    This looks like this clang bug:

    http://llvm.org/bugs/show_bug.cgi?id=12208

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
Does anyone know how can I replace this 2 symbol below from the string
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
link Im having trouble converting the html entites into html characters, (&# 8217;) i
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I am trying to render a haml file in a javascript response like so:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.