Hi,

# cat caller.cpp
struct ObjectAddress
{
protected:
  unsigned int m_a;
  unsigned int m_b;

public:
  ObjectAddress(long a, long b) : m_a(a), m_b(b) {}

  /* CASE 1: non-default constructor
     instance of ObjectAddress (x in main()) is passed by reference
  */
  ~ObjectAddress() {}

  /* CASE 2: default constructor
     instance of ObjectAddress (x in main()) is passed by value,
     as expected
  */
};

void test(ObjectAddress x);

int main()
{
  ObjectAddress addr(0xcafebabe, 0xdeadbeef);
  test(addr);
}

# cat callee.cpp
#include <stdio.h>

struct ObjectAddress
{
  unsigned int a;
  unsigned int b;
};

void test(ObjectAddress x)
{
  if(x.a == 0xcafebabe && x.b == 0xdeadbeef) {
    printf("Success: x was passed by value\n");
  }
  else {
    printf("Error: x was passed by reference\n");
  }
}

I compiled as follows:

  g++ -Wall -c caller.cpp -o caller.o
  g++ -Wall -c callee.cpp -o callee.o
  g++ -o test caller.o callee.o

The execution wrongly yields:

  # ./test
  Error: x was passed by reference

The ObjectAddress instance is passed by reference (struct ObjectAddress member
'a' on callee.cpp contains a pointer referencing the instance on the stack),
although the code suggests otherwise. If I remove the constructor declaration
from struct ObjectAddress in caller.cpp, the ObjectAddress instance is passed by
value, as expected. IMHO, x should be passed by value in all cases, a
non-default destructor should not make any difference.

I cannot reproduce this behavior using MSVC++ or Intel C++ Compiler 7.0, in both
cases, x is passed by value (whether or not the destructor exists).

I hope that you can shade some light on this issue!

Cheers,

Horst.

--
# gcc -v
Reading specs from /opt/gcc/3.4.2/lib/gcc/i686-pc-linux-gnu/3.4.2/specs
Configured with: ./configure --prefix=/opt/gcc/3.4.2
Thread model: posix
gcc version 3.4.2 20040829 (prerelease)

# uname -a
Linux englnx03 2.4.21-20.ELsmp #1 SMP Wed Aug 18 20:46:40 EDT 2004 i686 i686
i386 GNU/Linux

-- 
           Summary: g++ passes struct by reference instead of by value if
                    non-default constructor exists
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: horst dot reiterer at fabasoft dot com
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18194

Reply via email to