public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: c++/3167: Copyconstructor not called when entering function (var args)
@ 2001-06-14 19:00 rodrigc
  0 siblings, 0 replies; 3+ messages in thread
From: rodrigc @ 2001-06-14 19:00 UTC (permalink / raw)
  To: artem, rodrigc, gcc-bugs, gcc-prs, nobody, philipp.bachmann

Synopsis: Copyconstructor not called when entering function (var args)

State-Changed-From-To: open->closed
State-Changed-By: rodrigc
State-Changed-When: Thu Jun 14 19:00:26 2001
State-Changed-Why:
    Not a bug.  Please refer to message from Artem Khodush,
    with reference to the C++ Standard.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=3167&database=gcc


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: c++/3167: Copyconstructor not called when entering function (var args)
@ 2001-06-13  9:16 Artem Khodush
  0 siblings, 0 replies; 3+ messages in thread
From: Artem Khodush @ 2001-06-13  9:16 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/3167; it has been noted by GNATS.

From: "Artem Khodush" <artem@duma.gov.ru>
To: <philipp.bachmann@obtree.com>
Cc: <gcc-gnats@gcc.gnu.org>, <gcc-bugs@gcc.gnu.org>
Subject: Re: c++/3167: Copyconstructor not called when entering function (var args)
Date: Wed, 13 Jun 2001 20:02:55 +0400

 >Subject: c++/3167: Copyconstructor not called when entering function (var args)
 
 This is not a bug.
 
 [Quote from the C++ standard begins]
 
 5.2.2 - Function call [expr.call]
 
 -6- A function can be declared to accept fewer arguments (by declaring default arguments (dcl.fct.default)) or more arguments (by
 using the ellipsis, ... dcl.fct) than the number of parameters in the function definition (dcl.fct.def). [Note: this implies that,
 except where the ellipsis (...) is used, a parameter is available for each argument. ]
 
 -7- When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the
 value of the argument by invoking va_arg (lib.support.runtime). The lvalue-to-rvalue (conv.lval), array-to-pointer (conv.array), and
 function-to-pointer (conv.func) standard conversions are performed on the argument expression. After these conversions, if the
 argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed. If the
 argument has a non-POD class type (clause class), the behavior is undefined.
 
 [Quote from the C++ standard ends]
 
 You've observed two kinds of undefined behaviour: with gcc, neither
 constructor nor destructor is called, with sun cc, only the constructor
 is called. The desired 'correct' behaviour can not be implemented
 in general case, because va_arg and constructors do not mix.
 
 
 
 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* c++/3167: Copyconstructor not called when entering function (var args)
@ 2001-06-13  7:26 philipp.bachmann
  0 siblings, 0 replies; 3+ messages in thread
From: philipp.bachmann @ 2001-06-13  7:26 UTC (permalink / raw)
  To: gcc-gnats

>Number:         3167
>Category:       c++
>Synopsis:       Copyconstructor not called when entering function (var args)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 13 07:26:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Philipp Bachmann
>Release:        g++ 2.95.3
>Organization:
>Environment:
Sun Solaris 7 SPARC
>Description:
The code provided compiles successfully with the warnings:
[583]$ g++ copyconstr2.c++
copyconstr2.c++: In function `int ellipses(char *, ...)':
copyconstr2.c++:70: warning: cannot pass objects of type `base_t' through `...'
copyconstr2.c++:70: warning: cannot pass objects of type `base_t' through `...'
copyconstr2.c++: In function `int main()':
copyconstr2.c++:84: warning: cannot pass objects of type `base_t' through `...'
(These warnings are issued only if "base_t" explicitly has a copy
constructor defined.)
If the code is run, the following happens:
[584]$ ./a.out            
"base_t::Constructor" called. Constructing 0xffbef2f0.
"main()": Secret is 42.
"ellipses()": Function entered.
"base_t::Copyconstructor" called. Constructing 0xffbef260.
"ellipses()": Strange: 42.
"ellipses()": Function ending.
"base_t::Destructor" called. Destroying 0xffbef260.
"main()": Function call over.
"base_t::Destructor" called. Destroying 0xffbef2f0.

If I understand, what's behind the scene, when calling a function, correctly, then I expect a call to
the copy constructor on entering the function, i.e. I would expect the hypothetical output
[584]$ ./a.out            
"base_t::Constructor" called. Constructing 0xffbef2f0.
"main()": Secret is 42.
"base_t::Copyconstructor" called. Constructing 0xfoo.
"ellipses()": Function entered.
"base_t::Copyconstructor" called. Constructing 0xffbef260.
"ellipses()": Strange: 42.
"ellipses()": Function ending.
"base_t::Destructor" called. Destroying 0xffbef260.
"base_t::Destructor" called. Destroying 0xfoo.
"main()": Function call over.
"base_t::Destructor" called. Destroying 0xffbef2f0.

There is no reason in my opinion, why the compiler needs any information
about the argument types of the _function_ called (because there is a variable
argument list, there is indeed no such information on all arguments but the
first one) to call the copy constructor to put a copy of "base" onto
the stack - the only information, the compiler needs to have (and it has, because
"base" is defined as "base_t" two lines before the call to the
"ellipses()" function) for calling the copy constructor is the
type of "base".

The call to the copyconstructor that can be seen, though,
results from the initialization of local variable "base" inside
of the function "ellipses()" and can easily be switched off
by undefining "COPY". This is correct behaviour.

I've compared g++'s behaviour with the one of Sun CC 6 Update 1 (unpatched).
Sun's compiler calls the copyconstructor when entering the function, but has another bug:
It never destoys the space constructed...
>How-To-Repeat:
[583]$ g++ copyconstr2.c++
[584]$ ./a.out
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="copyconstr2.c++.txt"
Content-Disposition: inline; filename="copyconstr2.c++.txt"

/* Very simple program to show two bugs in two different compilers:

   Sun Forte 6 Update 1 (unpatched) calls "base_t::base_t(const base_t &)"
   on calling "ellipses("",CAST base)" even if "CAST" is replaced by
   nothing - but will never call "base_t::~base_t(void)" to
   destroy the copyconstructed formal parameter; if "CAST" is
   defined to be "(base_t)", then "base_t::base_t(const base_t &)" is
   called twice, but "base_t::~base_t(void)" is called only once to
   destroy the temporary instance resulting from the cast operation.
   
   GNU g++ 2.95.3, however, only calles "base_t::base_t(const base_t &)",
   "on" entering the function, if the argument "base" in the function
   call is explicitly casted to its own type; expected behaviour was
   to always cast the copyconstructor at least once on entering
   the function. */

/* $Log: copyconstr2.c++,v $
 * Revision 1.2  2001/06/13 14:55:15  bachlipp
 * Introduced "COPY" #define. Slightly presiced comment on
 * g++ behaviour.
 *
 * Revision 1.1  2001/06/13 10:34:26  bachlipp
 * Initial revision
 * */

static const char rcsid[]="@@(#)$Id: copyconstr2.c++,v 1.2 2001/06/13 14:55:15 bachlipp Exp $";

#include<iostream>
#include<stdio.h>
#include<cstdarg>

#define CAST

// #define CAST (base_t)

#define COPY

class base_t {
public :
  base_t(void);
  base_t(const base_t &);
  virtual ~base_t(void);
  static const int secret;
};

base_t::base_t(void) {
  std::cerr<<"\"base_t::Constructor\" called. Constructing "<<this<<"."<<std::endl;
}

base_t::base_t(const base_t &org) {
  std::cerr<<"\"base_t::Copyconstructor\" called. Constructing "<<this<<"."<<std::endl;
}

base_t::~base_t(void) {
  std::cerr<<"\"base_t::Destructor\" called. Destroying "<<this<<"."<<std::endl;
}

const int base_t::secret=42;

int ellipses(char *fmt, ...);

int ellipses(char *fmt, ...)
{
  std::cerr<<"\"ellipses()\": Function entered."<<std::endl;
  int retval;
  va_list arg;
  va_start(arg,fmt);
  base_t base
  #ifdef COPY
    =va_arg(arg,base_t)
  #else
    ; base=va_arg(arg,base_t)
  #endif
  ;
  retval=fprintf(stderr,"\"ellipses()\": Strange: %d.\n",base.secret);
  va_end(arg);
  std::cerr<<"\"ellipses()\": Function ending."<<std::endl;
  return retval;
}

int main() {
  base_t base;
  std::cerr<<"\"main()\": Secret is "<<base.secret<<"."<<std::endl;
  ellipses("",CAST base);
  std::cerr<<"\"main()\": Function call over."<<std::endl;
  return 0;
}


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-06-14 19:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-14 19:00 c++/3167: Copyconstructor not called when entering function (var args) rodrigc
  -- strict thread matches above, loose matches on Subject: below --
2001-06-13  9:16 Artem Khodush
2001-06-13  7:26 philipp.bachmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).